Home | History | Annotate | Download | only in history
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_HISTORY_EXPIRE_HISTORY_BACKEND_H_
      6 #define CHROME_BROWSER_HISTORY_EXPIRE_HISTORY_BACKEND_H_
      7 #pragma once
      8 
      9 #include <queue>
     10 #include <set>
     11 #include <vector>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/gtest_prod_util.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/task.h"
     17 #include "base/time.h"
     18 #include "chrome/browser/history/history_types.h"
     19 
     20 class BookmarkService;
     21 class GURL;
     22 class NotificationType;
     23 class TestingProfile;
     24 
     25 namespace history {
     26 
     27 class ArchivedDatabase;
     28 class HistoryDatabase;
     29 struct HistoryDetails;
     30 class TextDatabaseManager;
     31 class ThumbnailDatabase;
     32 
     33 // Delegate used to broadcast notifications to the main thread.
     34 class BroadcastNotificationDelegate {
     35  public:
     36   // Schedules a broadcast of the given notification on the application main
     37   // thread. The details argument will have ownership taken by this function.
     38   virtual void BroadcastNotifications(NotificationType type,
     39                                       HistoryDetails* details_deleted) = 0;
     40 
     41  protected:
     42   virtual ~BroadcastNotificationDelegate() {}
     43 };
     44 
     45 // Encapsulates visit expiration criteria and type of visits to expire.
     46 class ExpiringVisitsReader {
     47  public:
     48   virtual ~ExpiringVisitsReader() {}
     49   // Populates |visits| from |db|, using provided |end_time| and |max_visits|
     50   // cap.
     51   virtual bool Read(base::Time end_time, HistoryDatabase* db,
     52                     VisitVector* visits, int max_visits) const = 0;
     53 };
     54 
     55 typedef std::vector<const ExpiringVisitsReader*> ExpiringVisitsReaders;
     56 
     57 // Helper component to HistoryBackend that manages expiration and deleting of
     58 // history, as well as moving data from the main database to the archived
     59 // database as it gets old.
     60 //
     61 // It will automatically start periodically archiving old history once you call
     62 // StartArchivingOldStuff().
     63 class ExpireHistoryBackend {
     64  public:
     65   // The delegate pointer must be non-NULL. We will NOT take ownership of it.
     66   // BookmarkService may be NULL. The BookmarkService is used when expiring
     67   // URLs so that we don't remove any URLs or favicons that are bookmarked
     68   // (visits are removed though).
     69   ExpireHistoryBackend(BroadcastNotificationDelegate* delegate,
     70                        BookmarkService* bookmark_service);
     71   ~ExpireHistoryBackend();
     72 
     73   // Completes initialization by setting the databases that this class will use.
     74   void SetDatabases(HistoryDatabase* main_db,
     75                     ArchivedDatabase* archived_db,
     76                     ThumbnailDatabase* thumb_db,
     77                     TextDatabaseManager* text_db);
     78 
     79   // Begins periodic expiration of history older than the given threshold. This
     80   // will continue until the object is deleted.
     81   void StartArchivingOldStuff(base::TimeDelta expiration_threshold);
     82 
     83   // Deletes everything associated with a URL.
     84   void DeleteURL(const GURL& url);
     85 
     86   // Removes all visits to restrict_urls (or all URLs if empty) in the given
     87   // time range, updating the URLs accordingly,
     88   void ExpireHistoryBetween(const std::set<GURL>& restrict_urls,
     89                             base::Time begin_time, base::Time end_time);
     90 
     91   // Archives all visits before and including the given time, updating the URLs
     92   // accordingly. This function is intended for migrating old databases
     93   // (which encompased all time) to the tiered structure and testing, and
     94   // probably isn't useful for anything else.
     95   void ArchiveHistoryBefore(base::Time end_time);
     96 
     97   // Returns the current time that we are archiving stuff to. This will return
     98   // the threshold in absolute time rather than a delta, so the caller should
     99   // not save it.
    100   base::Time GetCurrentArchiveTime() const {
    101     return base::Time::Now() - expiration_threshold_;
    102   }
    103 
    104  private:
    105   FRIEND_TEST_ALL_PREFIXES(ExpireHistoryTest, DeleteTextIndexForURL);
    106   FRIEND_TEST_ALL_PREFIXES(ExpireHistoryTest, DeleteFaviconsIfPossible);
    107   FRIEND_TEST_ALL_PREFIXES(ExpireHistoryTest, ArchiveSomeOldHistory);
    108   FRIEND_TEST_ALL_PREFIXES(ExpireHistoryTest, ExpiringVisitsReader);
    109   FRIEND_TEST_ALL_PREFIXES(ExpireHistoryTest, ArchiveSomeOldHistoryWithSource);
    110   friend class ::TestingProfile;
    111 
    112   struct DeleteDependencies;
    113 
    114   // Removes the data from the full text index associated with the given URL
    115   // string/ID pair. If |update_visits| is set, the visits that reference the
    116   // indexed data will be updated to reflect the fact that the indexed data is
    117   // gone. Setting this to false is a performance optimization when the caller
    118   // knows that the visits will be deleted after the call.
    119   //
    120   // TODO(brettw) when we have an "archived" history database, this should take
    121   // a flag to optionally delete from there. This way it can be used for page
    122   // re-indexing as well as for full URL deletion.
    123   void DeleteTextIndexForURL(const GURL& url, URLID url_id, bool update_visits);
    124 
    125   // Deletes the visit-related stuff for all the visits in the given list, and
    126   // adds the rows for unique URLs affected to the affected_urls list in
    127   // the dependencies structure.
    128   //
    129   // Deleted information is the visits themselves and the full-text index
    130   // entries corresponding to them.
    131   void DeleteVisitRelatedInfo(const VisitVector& visits,
    132                               DeleteDependencies* dependencies);
    133 
    134   // Moves the given visits from the main database to the archived one.
    135   void ArchiveVisits(const VisitVector& visits);
    136 
    137   // Finds or deletes dependency information for the given URL. Information that
    138   // is specific to this URL (URL row, thumbnails, full text indexed stuff,
    139   // etc.) is deleted.
    140   //
    141   // This does not affect the visits! This is used for expiration as well as
    142   // deleting from the UI, and they handle visits differently.
    143   //
    144   // Other information will be collected and returned in the output containers.
    145   // This includes some of the things deleted that are needed elsewhere, plus
    146   // some things like favicons that could be shared by many URLs, and need to
    147   // be checked for deletion (this allows us to delete many URLs with only one
    148   // check for shared information at the end).
    149   //
    150   // Assumes the main_db_ is non-NULL.
    151   //
    152   // NOTE: If the url is bookmarked only the segments and text db are updated,
    153   // everything else is unchanged. This is done so that bookmarks retain their
    154   // favicons and thumbnails.
    155   void DeleteOneURL(const URLRow& url_row,
    156                     bool is_bookmarked,
    157                     DeleteDependencies* dependencies);
    158 
    159   // Adds or merges the given URL row with the archived database, returning the
    160   // ID of the URL in the archived database, or 0 on failure. The main (source)
    161   // database will not be affected (the URL will have to be deleted later).
    162   //
    163   // Assumes the archived database is not NULL.
    164   URLID ArchiveOneURL(const URLRow& url_row);
    165 
    166   // Deletes all the URLs in the given vector and handles their dependencies.
    167   // This will delete starred URLs
    168   void DeleteURLs(const std::vector<URLRow>& urls,
    169                   DeleteDependencies* dependencies);
    170 
    171   // Expiration involves removing visits, then propagating the visits out from
    172   // there and delete any orphaned URLs. These will be added to the deleted URLs
    173   // field of the dependencies and DeleteOneURL will handle deleting out from
    174   // there. This function does not handle favicons.
    175   //
    176   // When a URL is not deleted and |archive| is not set, the last visit time and
    177   // the visit and typed counts will be updated (we want to clear these when a
    178   // user is deleting history manually, but not when we're normally expiring old
    179   // things from history).
    180   //
    181   // The visits in the given vector should have already been deleted from the
    182   // database, and the list of affected URLs already be filled into
    183   // |depenencies->affected_urls|.
    184   //
    185   // Starred URLs will not be deleted. The information in the dependencies that
    186   // DeleteOneURL fills in will be updated, and this function will also delete
    187   // any now-unused favicons.
    188   void ExpireURLsForVisits(const VisitVector& visits,
    189                            DeleteDependencies* dependencies);
    190 
    191   // Creates entries in the archived database for the unique URLs referenced
    192   // by the given visits. It will then add versions of the visits to that
    193   // database. The source database WILL NOT BE MODIFIED. The source URLs and
    194   // visits will have to be deleted in another pass.
    195   //
    196   // The affected URLs will be filled into the given dependencies structure.
    197   void ArchiveURLsAndVisits(const VisitVector& visits,
    198                             DeleteDependencies* dependencies);
    199 
    200   // Deletes the favicons listed in the set if unused. Fails silently (we don't
    201   // care about favicons so much, so don't want to stop everything if it fails).
    202   void DeleteFaviconsIfPossible(const std::set<FaviconID>& favicon_id);
    203 
    204   // Broadcast the URL deleted notification.
    205   void BroadcastDeleteNotifications(DeleteDependencies* dependencies);
    206 
    207   // Schedules a call to DoArchiveIteration.
    208   void ScheduleArchive();
    209 
    210   // Calls ArchiveSomeOldHistory to expire some amount of old history, according
    211   // to the items in work queue, and schedules another call to happen in the
    212   // future.
    213   void DoArchiveIteration();
    214 
    215   // Tries to expire the oldest |max_visits| visits from history that are older
    216   // than |time_threshold|. The return value indicates if we think there might
    217   // be more history to expire with the current time threshold (it does not
    218   // indicate success or failure).
    219   bool ArchiveSomeOldHistory(base::Time end_time,
    220                              const ExpiringVisitsReader* reader,
    221                              int max_visits);
    222 
    223   // Tries to detect possible bad history or inconsistencies in the database
    224   // and deletes items. For example, URLs with no visits.
    225   void ParanoidExpireHistory();
    226 
    227   // Schedules a call to DoExpireHistoryIndexFiles.
    228   void ScheduleExpireHistoryIndexFiles();
    229 
    230   // Deletes old history index files.
    231   void DoExpireHistoryIndexFiles();
    232 
    233   // Returns the BookmarkService, blocking until it is loaded. This may return
    234   // NULL.
    235   BookmarkService* GetBookmarkService();
    236 
    237   // Initializes periodic expiration work queue by populating it with with tasks
    238   // for all known readers.
    239   void InitWorkQueue();
    240 
    241   // Returns the reader for all visits. This method is only used by the unit
    242   // tests.
    243   const ExpiringVisitsReader* GetAllVisitsReader();
    244 
    245   // Returns the reader for AUTO_SUBFRAME visits. This method is only used by
    246   // the unit tests.
    247   const ExpiringVisitsReader* GetAutoSubframeVisitsReader();
    248 
    249   // Non-owning pointer to the notification delegate (guaranteed non-NULL).
    250   BroadcastNotificationDelegate* delegate_;
    251 
    252   // Non-owning pointers to the databases we deal with (MAY BE NULL).
    253   HistoryDatabase* main_db_;       // Main history database.
    254   ArchivedDatabase* archived_db_;  // Old history.
    255   ThumbnailDatabase* thumb_db_;    // Thumbnails and favicons.
    256   TextDatabaseManager* text_db_;   // Full text index.
    257 
    258   // Used to generate runnable methods to do timers on this class. They will be
    259   // automatically canceled when this class is deleted.
    260   ScopedRunnableMethodFactory<ExpireHistoryBackend> factory_;
    261 
    262   // The threshold for "old" history where we will automatically expire it to
    263   // the archived database.
    264   base::TimeDelta expiration_threshold_;
    265 
    266   // List of all distinct types of readers. This list is used to populate the
    267   // work queue.
    268   ExpiringVisitsReaders readers_;
    269 
    270   // Work queue for periodic expiration tasks, used by DoArchiveIteration() to
    271   // determine what to do at an iteration, as well as populate it for future
    272   // iterations.
    273   std::queue<const ExpiringVisitsReader*> work_queue_;
    274 
    275   // Readers for various types of visits.
    276   // TODO(dglazkov): If you are adding another one, please consider reorganizing
    277   // into a map.
    278   scoped_ptr<ExpiringVisitsReader> all_visits_reader_;
    279   scoped_ptr<ExpiringVisitsReader> auto_subframe_visits_reader_;
    280 
    281   // The BookmarkService; may be null. This is owned by the Profile.
    282   //
    283   // Use GetBookmarkService to access this, which makes sure the service is
    284   // loaded.
    285   BookmarkService* bookmark_service_;
    286 
    287   DISALLOW_COPY_AND_ASSIGN(ExpireHistoryBackend);
    288 };
    289 
    290 }  // namespace history
    291 
    292 #endif  // CHROME_BROWSER_HISTORY_EXPIRE_HISTORY_BACKEND_H_
    293