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_HISTORY_BACKEND_H_
      6 #define CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_
      7 #pragma once
      8 
      9 #include <string>
     10 #include <utility>
     11 
     12 #include "app/sql/init_status.h"
     13 #include "base/file_path.h"
     14 #include "base/gtest_prod_util.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "chrome/browser/history/archived_database.h"
     17 #include "chrome/browser/history/expire_history_backend.h"
     18 #include "chrome/browser/history/history_database.h"
     19 #include "chrome/browser/history/history_marshaling.h"
     20 #include "chrome/browser/history/history_types.h"
     21 #include "chrome/browser/history/text_database_manager.h"
     22 #include "chrome/browser/history/thumbnail_database.h"
     23 #include "chrome/browser/history/visit_tracker.h"
     24 #include "chrome/browser/search_engines/template_url_id.h"
     25 #include "content/common/mru_cache.h"
     26 
     27 class BookmarkService;
     28 struct DownloadCreateInfo;
     29 class TestingProfile;
     30 struct ThumbnailScore;
     31 
     32 namespace history {
     33 
     34 class CommitLaterTask;
     35 class HistoryPublisher;
     36 
     37 // *See the .cc file for more information on the design.*
     38 //
     39 // Internal history implementation which does most of the work of the history
     40 // system. This runs on a background thread (to not block the browser when we
     41 // do expensive operations) and is NOT threadsafe, so it must only be called
     42 // from message handlers on the background thread. Invoking on another thread
     43 // requires threadsafe refcounting.
     44 //
     45 // Most functions here are just the implementations of the corresponding
     46 // functions in the history service. These functions are not documented
     47 // here, see the history service for behavior.
     48 class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
     49                        public BroadcastNotificationDelegate {
     50  public:
     51   // Interface implemented by the owner of the HistoryBackend object. Normally,
     52   // the history service implements this to send stuff back to the main thread.
     53   // The unit tests can provide a different implementation if they don't have
     54   // a history service object.
     55   class Delegate {
     56    public:
     57     virtual ~Delegate() {}
     58 
     59     // Called when the database cannot be read correctly for some reason.
     60     virtual void NotifyProfileError(sql::InitStatus init_status) = 0;
     61 
     62     // Sets the in-memory history backend. The in-memory backend is created by
     63     // the main backend. For non-unit tests, this happens on the background
     64     // thread. It is to be used on the main thread, so this would transfer
     65     // it to the history service. Unit tests can override this behavior.
     66     //
     67     // This function is NOT guaranteed to be called. If there is an error,
     68     // there may be no in-memory database.
     69     //
     70     // Ownership of the backend pointer is transferred to this function.
     71     virtual void SetInMemoryBackend(InMemoryHistoryBackend* backend) = 0;
     72 
     73     // Broadcasts the specified notification to the notification service.
     74     // This is implemented here because notifications must only be sent from
     75     // the main thread.
     76     //
     77     // Ownership of the HistoryDetails is transferred to this function.
     78     virtual void BroadcastNotifications(NotificationType type,
     79                                         HistoryDetails* details) = 0;
     80 
     81     // Invoked when the backend has finished loading the db.
     82     virtual void DBLoaded() = 0;
     83 
     84     // Tell TopSites to start reading thumbnails from the ThumbnailsDB.
     85     virtual void StartTopSitesMigration() = 0;
     86   };
     87 
     88   // Init must be called to complete object creation. This object can be
     89   // constructed on any thread, but all other functions including Init() must
     90   // be called on the history thread.
     91   //
     92   // |history_dir| is the directory where the history files will be placed.
     93   // See the definition of BroadcastNotificationsCallback above. This function
     94   // takes ownership of the callback pointer.
     95   //
     96   // |bookmark_service| is used to determine bookmarked URLs when deleting and
     97   // may be NULL.
     98   //
     99   // This constructor is fast and does no I/O, so can be called at any time.
    100   HistoryBackend(const FilePath& history_dir,
    101                  Delegate* delegate,
    102                  BookmarkService* bookmark_service);
    103 
    104   // Must be called after creation but before any objects are created. If this
    105   // fails, all other functions will fail as well. (Since this runs on another
    106   // thread, we don't bother returning failure.)
    107   //
    108   // |languages| gives a list of language encodings with which the history
    109   // URLs and omnibox searches are interpreted.
    110   // |force_fail| can be set during unittests to unconditionally fail to init.
    111   void Init(const std::string& languages, bool force_fail);
    112 
    113   // Notification that the history system is shutting down. This will break
    114   // the refs owned by the delegate and any pending transaction so it will
    115   // actually be deleted.
    116   void Closing();
    117 
    118   // See NotifyRenderProcessHostDestruction.
    119   void NotifyRenderProcessHostDestruction(const void* host);
    120 
    121   // Navigation ----------------------------------------------------------------
    122 
    123   void AddPage(scoped_refptr<HistoryAddPageArgs> request);
    124   virtual void SetPageTitle(const GURL& url, const string16& title);
    125   void AddPageNoVisitForBookmark(const GURL& url);
    126 
    127   // Indexing ------------------------------------------------------------------
    128 
    129   void SetPageContents(const GURL& url, const string16& contents);
    130 
    131   // Querying ------------------------------------------------------------------
    132 
    133   // ScheduleAutocomplete() never frees |provider| (which is globally live).
    134   // It passes |params| on to the autocomplete system which will eventually
    135   // free it.
    136   void ScheduleAutocomplete(HistoryURLProvider* provider,
    137                             HistoryURLProviderParams* params);
    138 
    139   void IterateURLs(HistoryService::URLEnumerator* enumerator);
    140   void QueryURL(scoped_refptr<QueryURLRequest> request,
    141                 const GURL& url,
    142                 bool want_visits);
    143   void QueryHistory(scoped_refptr<QueryHistoryRequest> request,
    144                     const string16& text_query,
    145                     const QueryOptions& options);
    146   void QueryRedirectsFrom(scoped_refptr<QueryRedirectsRequest> request,
    147                           const GURL& url);
    148   void QueryRedirectsTo(scoped_refptr<QueryRedirectsRequest> request,
    149                         const GURL& url);
    150 
    151   void GetVisitCountToHost(scoped_refptr<GetVisitCountToHostRequest> request,
    152                            const GURL& url);
    153 
    154   // TODO(Nik): remove. Use QueryMostVisitedURLs instead.
    155   void QueryTopURLsAndRedirects(
    156       scoped_refptr<QueryTopURLsAndRedirectsRequest> request,
    157       int result_count);
    158 
    159   // Request the |result_count| most visited URLs and the chain of
    160   // redirects leading to each of these URLs. |days_back| is the
    161   // number of days of history to use. Used by TopSites.
    162   void QueryMostVisitedURLs(
    163       scoped_refptr<QueryMostVisitedURLsRequest> request,
    164       int result_count,
    165       int days_back);
    166 
    167   // QueryMostVisitedURLs without the request.
    168   void QueryMostVisitedURLsImpl(int result_count,
    169                                 int days_back,
    170                                 MostVisitedURLList* result);
    171 
    172   // Computes the most recent URL(s) that the given canonical URL has
    173   // redirected to and returns true on success. There may be more than one
    174   // redirect in a row, so this function will fill the given array with the
    175   // entire chain. If there are no redirects for the most recent visit of the
    176   // URL, or the URL is not in history, returns false.
    177   //
    178   // Backend for QueryRedirectsFrom.
    179   bool GetMostRecentRedirectsFrom(const GURL& url,
    180                                   history::RedirectList* redirects);
    181 
    182   // Similar to above function except computes a chain of redirects to the
    183   // given URL. Stores the most recent list of redirects ending at |url| in the
    184   // given RedirectList. For example, if we have the redirect list A -> B -> C,
    185   // then calling this function with url=C would fill redirects with {B, A}.
    186   bool GetMostRecentRedirectsTo(const GURL& url,
    187                                       history::RedirectList* redirects);
    188 
    189   // Thumbnails ----------------------------------------------------------------
    190 
    191   void SetPageThumbnail(const GURL& url,
    192                         const SkBitmap& thumbnail,
    193                         const ThumbnailScore& score);
    194 
    195   // Retrieves a thumbnail, passing it across thread boundaries
    196   // via. the included callback.
    197   void GetPageThumbnail(scoped_refptr<GetPageThumbnailRequest> request,
    198                         const GURL& page_url);
    199 
    200   // Backend implementation of GetPageThumbnail. Unlike
    201   // GetPageThumbnail(), this method has way to transport data across
    202   // thread boundaries.
    203   //
    204   // Exposed for testing reasons.
    205   void GetPageThumbnailDirectly(
    206       const GURL& page_url,
    207       scoped_refptr<RefCountedBytes>* data);
    208 
    209   void MigrateThumbnailsDatabase();
    210 
    211   // Favicon -------------------------------------------------------------------
    212 
    213   void GetFavicon(scoped_refptr<GetFaviconRequest> request,
    214                   const GURL& icon_url,
    215                   int icon_types);
    216 
    217   void GetFaviconForURL(scoped_refptr<GetFaviconRequest> request,
    218                         const GURL& page_url,
    219                         int icon_types);
    220 
    221   void SetFavicon(const GURL& page_url,
    222                   const GURL& icon_url,
    223                   scoped_refptr<RefCountedMemory> data,
    224                   IconType icon_type);
    225 
    226   void UpdateFaviconMappingAndFetch(scoped_refptr<GetFaviconRequest> request,
    227                                     const GURL& page_url,
    228                                     const GURL& icon_url,
    229                                     IconType icon_type);
    230 
    231   void SetFaviconOutOfDateForPage(const GURL& page_url);
    232 
    233   void SetImportedFavicons(
    234       const std::vector<ImportedFaviconUsage>& favicon_usage);
    235 
    236   // Downloads -----------------------------------------------------------------
    237 
    238   void QueryDownloads(scoped_refptr<DownloadQueryRequest> request);
    239   void CleanUpInProgressEntries();
    240   void UpdateDownload(int64 received_bytes, int32 state, int64 db_handle);
    241   void UpdateDownloadPath(const FilePath& path, int64 db_handle);
    242   void CreateDownload(scoped_refptr<DownloadCreateRequest> request,
    243                       const DownloadCreateInfo& info);
    244   void RemoveDownload(int64 db_handle);
    245   void RemoveDownloadsBetween(const base::Time remove_begin,
    246                               const base::Time remove_end);
    247   void RemoveDownloads(const base::Time remove_end);
    248 
    249   // Segment usage -------------------------------------------------------------
    250 
    251   void QuerySegmentUsage(scoped_refptr<QuerySegmentUsageRequest> request,
    252                          const base::Time from_time,
    253                          int max_result_count);
    254   void DeleteOldSegmentData();
    255   void SetSegmentPresentationIndex(SegmentID segment_id, int index);
    256 
    257   // Keyword search terms ------------------------------------------------------
    258 
    259   void SetKeywordSearchTermsForURL(const GURL& url,
    260                                    TemplateURLID keyword_id,
    261                                    const string16& term);
    262 
    263   void DeleteAllSearchTermsForKeyword(TemplateURLID keyword_id);
    264 
    265   void GetMostRecentKeywordSearchTerms(
    266       scoped_refptr<GetMostRecentKeywordSearchTermsRequest> request,
    267       TemplateURLID keyword_id,
    268       const string16& prefix,
    269       int max_count);
    270 
    271   // Generic operations --------------------------------------------------------
    272 
    273   void ProcessDBTask(scoped_refptr<HistoryDBTaskRequest> request);
    274 
    275   virtual bool GetAllTypedURLs(std::vector<history::URLRow>* urls);
    276 
    277   virtual bool GetVisitsForURL(URLID id, VisitVector* visits);
    278 
    279   virtual bool UpdateURL(URLID id, const history::URLRow& url);
    280 
    281   // While adding visits in batch, the source needs to be provided.
    282   virtual bool AddVisits(const GURL& url,
    283                          const std::vector<base::Time>& visits,
    284                          VisitSource visit_source);
    285 
    286   virtual bool RemoveVisits(const VisitVector& visits);
    287 
    288   virtual bool GetURL(const GURL& url, history::URLRow* url_row);
    289 
    290   // Deleting ------------------------------------------------------------------
    291 
    292   virtual void DeleteURLs(const std::vector<GURL>& urls);
    293 
    294   virtual void DeleteURL(const GURL& url);
    295 
    296   // Calls ExpireHistoryBackend::ExpireHistoryBetween and commits the change.
    297   void ExpireHistoryBetween(scoped_refptr<ExpireHistoryRequest> request,
    298                             const std::set<GURL>& restrict_urls,
    299                             base::Time begin_time,
    300                             base::Time end_time);
    301 
    302   // Bookmarks -----------------------------------------------------------------
    303 
    304   // Notification that a URL is no longer bookmarked. If there are no visits
    305   // for the specified url, it is deleted.
    306   void URLsNoLongerBookmarked(const std::set<GURL>& urls);
    307 
    308   // Testing -------------------------------------------------------------------
    309 
    310   // Sets the task to run and the message loop to run it on when this object
    311   // is destroyed. See HistoryService::SetOnBackendDestroyTask for a more
    312   // complete description.
    313   void SetOnBackendDestroyTask(MessageLoop* message_loop, Task* task);
    314 
    315   // Adds the given rows to the database if it doesn't exist. A visit will be
    316   // added for each given URL at the last visit time in the URLRow.
    317   // Each visit will have the visit_source type set.
    318   void AddPagesWithDetails(const std::vector<URLRow>& info,
    319                            VisitSource visit_source);
    320 
    321 #if defined(UNIT_TEST)
    322   HistoryDatabase* db() const { return db_.get(); }
    323 
    324   ExpireHistoryBackend* expire_backend() { return &expirer_; }
    325 #endif
    326 
    327  protected:
    328   virtual ~HistoryBackend();
    329 
    330  private:
    331   friend class base::RefCountedThreadSafe<HistoryBackend>;
    332   friend class CommitLaterTask;  // The commit task needs to call Commit().
    333   friend class HistoryBackendTest;
    334   friend class HistoryTest;  // So the unit tests can poke our innards.
    335   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteAll);
    336   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, ImportedFaviconsTest);
    337   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, URLsNoLongerBookmarked);
    338   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, StripUsernamePasswordTest);
    339   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, DeleteThumbnailsDatabaseTest);
    340   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPageVisitSource);
    341   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddPageArgsSource);
    342   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddVisitsSource);
    343   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, RemoveVisitsSource);
    344   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MigrationVisitSource);
    345   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, MigrationIconMapping);
    346   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, SetFaviconMapping);
    347   FRIEND_TEST_ALL_PREFIXES(HistoryBackendTest, AddOrUpdateIconMapping);
    348 
    349   friend class ::TestingProfile;
    350 
    351   // Computes the name of the specified database on disk.
    352   FilePath GetThumbnailFileName() const;
    353 
    354   // Returns the name of the Favicons database. This is the new name
    355   // of the Thumbnails database.
    356   // See ThumbnailDatabase::RenameAndDropThumbnails.
    357   FilePath GetFaviconsFileName() const;
    358   FilePath GetArchivedFileName() const;
    359 
    360   class URLQuerier;
    361   friend class URLQuerier;
    362 
    363   // Does the work of Init.
    364   void InitImpl(const std::string& languages);
    365 
    366   // Adds a single visit to the database, updating the URL information such
    367   // as visit and typed count. The visit ID of the added visit and the URL ID
    368   // of the associated URL (whether added or not) is returned. Both values will
    369   // be 0 on failure.
    370   //
    371   // This does not schedule database commits, it is intended to be used as a
    372   // subroutine for AddPage only. It also assumes the database is valid.
    373   std::pair<URLID, VisitID> AddPageVisit(const GURL& url,
    374                                          base::Time time,
    375                                          VisitID referring_visit,
    376                                          PageTransition::Type transition,
    377                                          VisitSource visit_source);
    378 
    379   // Returns a redirect chain in |redirects| for the VisitID
    380   // |cur_visit|. |cur_visit| is assumed to be valid. Assumes that
    381   // this HistoryBackend object has been Init()ed successfully.
    382   void GetRedirectsFromSpecificVisit(
    383       VisitID cur_visit, history::RedirectList* redirects);
    384 
    385   // Similar to the above function except returns a redirect list ending
    386   // at |cur_visit|.
    387   void GetRedirectsToSpecificVisit(
    388       VisitID cur_visit, history::RedirectList* redirects);
    389 
    390   // Thumbnail Helpers ---------------------------------------------------------
    391 
    392   // When a simple GetMostRecentRedirectsFrom() fails, this method is
    393   // called which searches the last N visit sessions instead of just
    394   // the current one. Returns true and puts thumbnail data in |data|
    395   // if a proper thumbnail was found. Returns false otherwise. Assumes
    396   // that this HistoryBackend object has been Init()ed successfully.
    397   bool GetThumbnailFromOlderRedirect(
    398       const GURL& page_url, std::vector<unsigned char>* data);
    399 
    400   // Querying ------------------------------------------------------------------
    401 
    402   // Backends for QueryHistory. *Basic() handles queries that are not FTS (full
    403   // text search) queries and can just be given directly to the history DB).
    404   // The FTS version queries the text_database, then merges with the history DB.
    405   // Both functions assume QueryHistory already checked the DB for validity.
    406   void QueryHistoryBasic(URLDatabase* url_db, VisitDatabase* visit_db,
    407                          const QueryOptions& options, QueryResults* result);
    408   void QueryHistoryFTS(const string16& text_query,
    409                        const QueryOptions& options,
    410                        QueryResults* result);
    411 
    412   // Committing ----------------------------------------------------------------
    413 
    414   // We always keep a transaction open on the history database so that multiple
    415   // transactions can be batched. Periodically, these are flushed (use
    416   // ScheduleCommit). This function does the commit to write any new changes to
    417   // disk and opens a new transaction. This will be called automatically by
    418   // ScheduleCommit, or it can be called explicitly if a caller really wants
    419   // to write something to disk.
    420   void Commit();
    421 
    422   // Schedules a commit to happen in the future. We do this so that many
    423   // operations over a period of time will be batched together. If there is
    424   // already a commit scheduled for the future, this will do nothing.
    425   void ScheduleCommit();
    426 
    427   // Cancels the scheduled commit, if any. If there is no scheduled commit,
    428   // does nothing.
    429   void CancelScheduledCommit();
    430 
    431   // Segments ------------------------------------------------------------------
    432 
    433   // Walks back a segment chain to find the last visit with a non null segment
    434   // id and returns it. If there is none found, returns 0.
    435   SegmentID GetLastSegmentID(VisitID from_visit);
    436 
    437   // Update the segment information. This is called internally when a page is
    438   // added. Return the segment id of the segment that has been updated.
    439   SegmentID UpdateSegments(const GURL& url,
    440                            VisitID from_visit,
    441                            VisitID visit_id,
    442                            PageTransition::Type transition_type,
    443                            const base::Time ts);
    444 
    445   // Favicons ------------------------------------------------------------------
    446 
    447   // Used by both UpdateFaviconMappingAndFetch and GetFavicon.
    448   // If page_url is non-null and SetFavicon has previously been invoked for
    449   // icon_url the favicon url for page_url (and all redirects) is set to
    450   // icon_url.
    451   // Only a single type can be given in icon_type when page_url is specified.
    452   void UpdateFaviconMappingAndFetchImpl(
    453       const GURL* page_url,
    454       const GURL& icon_url,
    455       scoped_refptr<GetFaviconRequest> request,
    456       int icon_type);
    457 
    458   // Sets the favicon url id for page_url to id. This will also broadcast
    459   // notifications as necessary.
    460   void SetFaviconMapping(const GURL& page_url,
    461                          FaviconID id,
    462                          IconType icon_type);
    463 
    464   // Updates the FaviconID associated with the url of a page. If there is an
    465   // existing mapping between |page_url| and |id| this does nothing and returns
    466   // false. If the mapping needs to be added or updated, true is returned. If
    467   // there is an existing mapping but it does not map to |id|, then the |id| of
    468   // the replaced FaviconID is set in |replaced_icon_id|.
    469   bool AddOrUpdateIconMapping(const GURL& page_url,
    470                               FaviconID id,
    471                               IconType icon_type,
    472                               FaviconID* replaced_icon_id);
    473 
    474   // Generic stuff -------------------------------------------------------------
    475 
    476   // Processes the next scheduled HistoryDBTask, scheduling this method
    477   // to be invoked again if there are more tasks that need to run.
    478   void ProcessDBTaskImpl();
    479 
    480   // Release all tasks in history_db_tasks_ and clears it.
    481   void ReleaseDBTasks();
    482 
    483   // Schedules a broadcast of the given notification on the main thread. The
    484   // details argument will have ownership taken by this function (it will be
    485   // sent to the main thread and deleted there).
    486   virtual void BroadcastNotifications(NotificationType type,
    487                                       HistoryDetails* details_deleted);
    488 
    489   // Deleting all history ------------------------------------------------------
    490 
    491   // Deletes all history. This is a special case of deleting that is separated
    492   // from our normal dependency-following method for performance reasons. The
    493   // logic lives here instead of ExpireHistoryBackend since it will cause
    494   // re-initialization of some databases such as Thumbnails or Archived that
    495   // could fail. When these databases are not valid, our pointers must be NULL,
    496   // so we need to handle this type of operation to keep the pointers in sync.
    497   void DeleteAllHistory();
    498 
    499   // Given a vector of all URLs that we will keep, removes all thumbnails
    500   // referenced by any URL, and also all favicons that aren't used by those
    501   // URLs. The favicon IDs will change, so this will update the url rows in the
    502   // vector to reference the new IDs.
    503   bool ClearAllThumbnailHistory(std::vector<URLRow>* kept_urls);
    504 
    505   // Deletes all information in the history database, except for the supplied
    506   // set of URLs in the URL table (these should correspond to the bookmarked
    507   // URLs).
    508   //
    509   // The IDs of the URLs may change.
    510   bool ClearAllMainHistory(const std::vector<URLRow>& kept_urls);
    511 
    512   // Returns the BookmarkService, blocking until it is loaded. This may return
    513   // NULL during testing.
    514   BookmarkService* GetBookmarkService();
    515 
    516   // Data ----------------------------------------------------------------------
    517 
    518   // Delegate. See the class definition above for more information. This will
    519   // be NULL before Init is called and after Cleanup, but is guaranteed
    520   // non-NULL in between.
    521   scoped_ptr<Delegate> delegate_;
    522 
    523   // Directory where database files will be stored.
    524   FilePath history_dir_;
    525 
    526   // The history/thumbnail databases. Either MAY BE NULL if the database could
    527   // not be opened, all users must first check for NULL and return immediately
    528   // if it is. The thumbnail DB may be NULL when the history one isn't, but not
    529   // vice-versa.
    530   scoped_ptr<HistoryDatabase> db_;
    531   scoped_ptr<ThumbnailDatabase> thumbnail_db_;
    532 
    533   // Stores old history in a larger, slower database.
    534   scoped_ptr<ArchivedDatabase> archived_db_;
    535 
    536   // Full text database manager, possibly NULL if the database could not be
    537   // created.
    538   scoped_ptr<TextDatabaseManager> text_database_;
    539 
    540   // Manages expiration between the various databases.
    541   ExpireHistoryBackend expirer_;
    542 
    543   // A commit has been scheduled to occur sometime in the future. We can check
    544   // non-null-ness to see if there is a commit scheduled in the future, and we
    545   // can use the pointer to cancel the scheduled commit. There can be only one
    546   // scheduled commit at a time (see ScheduleCommit).
    547   scoped_refptr<CommitLaterTask> scheduled_commit_;
    548 
    549   // Maps recent redirect destination pages to the chain of redirects that
    550   // brought us to there. Pages that did not have redirects or were not the
    551   // final redirect in a chain will not be in this list, as well as pages that
    552   // redirected "too long" ago (as determined by ExpireOldRedirects above).
    553   // It is used to set titles & favicons for redirects to that of the
    554   // destination.
    555   //
    556   // As with AddPage, the last item in the redirect chain will be the
    557   // destination of the redirect (i.e., the key into recent_redirects_);
    558   typedef MRUCache<GURL, history::RedirectList> RedirectCache;
    559   RedirectCache recent_redirects_;
    560 
    561   // Timestamp of the last page addition request. We use this to detect when
    562   // multiple additions are requested at the same time (within the resolution
    563   // of the timer), so we can try to ensure they're unique when they're added
    564   // to the database by using the last_recorded_time_ (q.v.). We still can't
    565   // enforce or guarantee uniqueness, since the user might set his clock back.
    566   base::Time last_requested_time_;
    567 
    568   // Timestamp of the last page addition, as it was recorded in the database.
    569   // If two or more requests come in at the same time, we increment that time
    570   // by 1 us between them so it's more likely to be unique in the database.
    571   // This keeps track of that higher-resolution timestamp.
    572   base::Time last_recorded_time_;
    573 
    574   // Timestamp of the first entry in our database.
    575   base::Time first_recorded_time_;
    576 
    577   // When non-NULL, this is the task that should be invoked on
    578   MessageLoop* backend_destroy_message_loop_;
    579   Task* backend_destroy_task_;
    580 
    581   // Tracks page transition types.
    582   VisitTracker tracker_;
    583 
    584   // A boolean variable to track whether we have already purged obsolete segment
    585   // data.
    586   bool segment_queried_;
    587 
    588   // HistoryDBTasks to run. Be sure to AddRef when adding, and Release when
    589   // done.
    590   std::list<HistoryDBTaskRequest*> db_task_requests_;
    591 
    592   // Used to determine if a URL is bookmarked. This is owned by the Profile and
    593   // may be NULL (during testing).
    594   //
    595   // Use GetBookmarkService to access this, which makes sure the service is
    596   // loaded.
    597   BookmarkService* bookmark_service_;
    598 
    599   // Publishes the history to all indexers which are registered to receive
    600   // history data from us. Can be NULL if there are no listeners.
    601   scoped_ptr<HistoryPublisher> history_publisher_;
    602 
    603   DISALLOW_COPY_AND_ASSIGN(HistoryBackend);
    604 };
    605 
    606 }  // namespace history
    607 
    608 #endif  // CHROME_BROWSER_HISTORY_HISTORY_BACKEND_H_
    609