history_types.h revision 513209b27ff55e2841eac0e4120199c23acce758
1// Copyright (c) 2010 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_TYPES_H_
6#define CHROME_BROWSER_HISTORY_HISTORY_TYPES_H_
7#pragma once
8
9#include <deque>
10#include <map>
11#include <set>
12#include <string>
13#include <vector>
14
15#include "base/basictypes.h"
16#include "base/ref_counted_memory.h"
17#include "base/stack_container.h"
18#include "base/string16.h"
19#include "base/time.h"
20#include "chrome/browser/history/snippet.h"
21#include "chrome/common/page_transition_types.h"
22#include "chrome/common/ref_counted_util.h"
23#include "chrome/common/thumbnail_score.h"
24#include "googleurl/src/gurl.h"
25
26namespace history {
27
28// Forward declaration for friend statements.
29class HistoryBackend;
30class URLDatabase;
31
32// Structure to hold redirect lists for URLs.  For a redirect chain
33// A -> B -> C, and entry in the map would look like "A => {B -> C}".
34typedef std::map<GURL, scoped_refptr<RefCountedVector<GURL> > > RedirectMap;
35
36// Container for a list of URLs.
37typedef std::vector<GURL> RedirectList;
38
39typedef int64 StarID;  // Unique identifier for star entries.
40typedef int64 UIStarID;  // Identifier for star entries that come from the UI.
41typedef int64 DownloadID;   // Identifier for a download.
42typedef int64 FavIconID;  // For FavIcons.
43typedef int64 SegmentID;  // URL segments for the most visited view.
44
45// URLRow ---------------------------------------------------------------------
46
47typedef int64 URLID;
48
49// Holds all information globally associated with one URL (one row in the
50// URL table).
51//
52// This keeps track of dirty bits, which are currently unused:
53//
54// TODO(brettw) the dirty bits are broken in a number of respects. First, the
55// database will want to update them on a const object, so they need to be
56// mutable.
57//
58// Second, there is a problem copying. If you make a copy of this structure
59// (as we allow since we put this into vectors in various places) then the
60// dirty bits will not be in sync for these copies.
61class URLRow {
62 public:
63  URLRow();
64
65  explicit URLRow(const GURL& url);
66
67  // We need to be able to set the id of a URLRow that's being passed through
68  // an IPC message.  This constructor should probably not be used otherwise.
69  URLRow(const GURL& url, URLID id);
70
71  virtual ~URLRow();
72  URLRow& operator=(const URLRow& other);
73
74  URLID id() const { return id_; }
75  const GURL& url() const { return url_; }
76
77  const string16& title() const {
78    return title_;
79  }
80  void set_title(const string16& title) {
81    // The title is frequently set to the same thing, so we don't bother
82    // updating unless the string has changed.
83    if (title != title_) {
84      title_ = title;
85    }
86  }
87
88  int visit_count() const {
89    return visit_count_;
90  }
91  void set_visit_count(int visit_count) {
92    visit_count_ = visit_count;
93  }
94
95  // Number of times the URL was typed in the Omnibox.
96  int typed_count() const {
97    return typed_count_;
98  }
99  void set_typed_count(int typed_count) {
100    typed_count_ = typed_count;
101  }
102
103  base::Time last_visit() const {
104    return last_visit_;
105  }
106  void set_last_visit(base::Time last_visit) {
107    last_visit_ = last_visit;
108  }
109
110  // If this is set, we won't autocomplete this URL.
111  bool hidden() const {
112    return hidden_;
113  }
114  void set_hidden(bool hidden) {
115    hidden_ = hidden;
116  }
117
118  // ID of the favicon. A value of 0 means the favicon isn't known yet.
119  FavIconID favicon_id() const { return favicon_id_; }
120  void set_favicon_id(FavIconID favicon_id) {
121    favicon_id_ = favicon_id;
122  }
123
124  // Swaps the contents of this URLRow with another, which allows it to be
125  // destructively copied without memory allocations.
126  // (Virtual because it's overridden by URLResult.)
127  virtual void Swap(URLRow* other);
128
129 private:
130  // This class writes directly into this structure and clears our dirty bits
131  // when reading out of the DB.
132  friend class URLDatabase;
133  friend class HistoryBackend;
134
135  // Initializes all values that need initialization to their defaults.
136  // This excludes objects which autoinitialize such as strings.
137  void Initialize();
138
139  // The row ID of this URL. Immutable except for the database which sets it
140  // when it pulls them out.
141  URLID id_;
142
143  // The URL of this row. Immutable except for the database which sets it
144  // when it pulls them out. If clients want to change it, they must use
145  // the constructor to make a new one.
146  GURL url_;
147
148  string16 title_;
149
150  // Total number of times this URL has been visited.
151  int visit_count_;
152
153  // Number of times this URL has been manually entered in the URL bar.
154  int typed_count_;
155
156  // The date of the last visit of this URL, which saves us from having to
157  // loop up in the visit table for things like autocomplete and expiration.
158  base::Time last_visit_;
159
160  // Indicates this entry should now be shown in typical UI or queries, this
161  // is usually for subframes.
162  bool hidden_;
163
164  // The ID of the favicon for this url.
165  FavIconID favicon_id_;
166
167  // We support the implicit copy constuctor and operator=.
168};
169
170// The enumeration of all possible sources of visits is listed below.
171// The source will be propogated along with a URL or a visit item
172// and eventually be stored in the history database,
173// visit_source table specifically.
174// Different from page transition types, they describe the origins of visits.
175// (Warning): Please don't change any existing values while it is ok to add
176// new values when needed.
177typedef enum {
178  SOURCE_SYNCED = 0,         // Synchronized from somewhere else.
179  SOURCE_BROWSED = 1,        // User browsed.
180  SOURCE_EXTENSION = 2,      // Added by an externsion.
181  SOURCE_FIREFOX_IMPORTED = 3,
182  SOURCE_IE_IMPORTED = 4,
183  SOURCE_SAFARI_IMPORTED = 5,
184} VisitSource;
185
186typedef int64 VisitID;
187// Structure to hold the mapping between each visit's id and its source.
188typedef std::map<VisitID, VisitSource> VisitSourceMap;
189
190// VisitRow -------------------------------------------------------------------
191
192// Holds all information associated with a specific visit. A visit holds time
193// and referrer information for one time a URL is visited.
194class VisitRow {
195 public:
196  VisitRow();
197  VisitRow(URLID arg_url_id,
198           base::Time arg_visit_time,
199           VisitID arg_referring_visit,
200           PageTransition::Type arg_transition,
201           SegmentID arg_segment_id);
202  ~VisitRow();
203
204  // ID of this row (visit ID, used a a referrer for other visits).
205  VisitID visit_id;
206
207  // Row ID into the URL table of the URL that this page is.
208  URLID url_id;
209
210  base::Time visit_time;
211
212  // Indicates another visit that was the referring page for this one.
213  // 0 indicates no referrer.
214  VisitID referring_visit;
215
216  // A combination of bits from PageTransition.
217  PageTransition::Type transition;
218
219  // The segment id (see visitsegment_database.*).
220  // If 0, the segment id is null in the table.
221  SegmentID segment_id;
222
223  // True when this visit has indexed data for it. We try to keep this in sync
224  // with the full text index: when we add or remove things from there, we will
225  // update the visit table as well. However, that file could get deleted, or
226  // out of sync in various ways, so this flag should be false when things
227  // change.
228  bool is_indexed;
229
230  // Compares two visits based on dates, for sorting.
231  bool operator<(const VisitRow& other) {
232    return visit_time < other.visit_time;
233  }
234
235  // We allow the implicit copy constuctor and operator=.
236};
237
238// We pass around vectors of visits a lot
239typedef std::vector<VisitRow> VisitVector;
240
241// Favicons -------------------------------------------------------------------
242
243// Used by the importer to set favicons for imported bookmarks.
244struct ImportedFavIconUsage {
245  ImportedFavIconUsage();
246  ~ImportedFavIconUsage();
247
248  // The URL of the favicon.
249  GURL favicon_url;
250
251  // The raw png-encoded data.
252  std::vector<unsigned char> png_data;
253
254  // The list of URLs using this favicon.
255  std::set<GURL> urls;
256};
257
258// PageVisit ------------------------------------------------------------------
259
260// Represents a simplified version of a visit for external users. Normally,
261// views are only interested in the time, and not the other information
262// associated with a VisitRow.
263struct PageVisit {
264  URLID page_id;
265  base::Time visit_time;
266};
267
268// StarredEntry ---------------------------------------------------------------
269
270// StarredEntry represents either a starred page, or a star grouping (where
271// a star grouping consists of child starred entries). Use the type to
272// determine the type of a particular entry.
273//
274// The database internally uses the id field to uniquely identify a starred
275// entry. On the other hand, the UI, which is anything routed through
276// HistoryService and HistoryBackend (including BookmarkBarView), uses the
277// url field to uniquely identify starred entries of type URL and the group_id
278// field to uniquely identify starred entries of type USER_GROUP. For example,
279// HistoryService::UpdateStarredEntry identifies the entry by url (if the
280// type is URL) or group_id (if the type is not URL).
281struct StarredEntry {
282  enum Type {
283    // Type represents a starred URL (StarredEntry).
284    URL,
285
286    // The bookmark bar grouping.
287    BOOKMARK_BAR,
288
289    // User created group.
290    USER_GROUP,
291
292    // The "other bookmarks" folder that holds uncategorized bookmarks.
293    OTHER
294  };
295
296  StarredEntry();
297  ~StarredEntry();
298
299  void Swap(StarredEntry* other);
300
301  // Unique identifier of this entry.
302  StarID id;
303
304  // Title.
305  string16 title;
306
307  // When this was added.
308  base::Time date_added;
309
310  // Group ID of the star group this entry is in. If 0, this entry is not
311  // in a star group.
312  UIStarID parent_group_id;
313
314  // Unique identifier for groups. This is assigned by the UI.
315  //
316  // WARNING: this is NOT the same as id, id is assigned by the database,
317  // this is assigned by the UI. See note about StarredEntry for more info.
318  UIStarID group_id;
319
320  // Visual order within the parent. Only valid if group_id is not 0.
321  int visual_order;
322
323  // Type of this entry (see enum).
324  Type type;
325
326  // If type == URL, this is the URL of the page that was starred.
327  GURL url;
328
329  // If type == URL, this is the ID of the URL of the primary page that was
330  // starred.
331  URLID url_id;
332
333  // Time the entry was last modified. This is only used for groups and
334  // indicates the last time a URL was added as a child to the group.
335  base::Time date_group_modified;
336};
337
338// URLResult -------------------------------------------------------------------
339
340class URLResult : public URLRow {
341 public:
342  URLResult();
343  URLResult(const GURL& url, base::Time visit_time);
344  // Constructor that create a URLResult from the specified URL and title match
345  // positions from title_matches.
346  URLResult(const GURL& url, const Snippet::MatchPositions& title_matches);
347  ~URLResult();
348
349  base::Time visit_time() const { return visit_time_; }
350  void set_visit_time(base::Time visit_time) { visit_time_ = visit_time; }
351
352  const Snippet& snippet() const { return snippet_; }
353
354  // If this is a title match, title_match_positions contains an entry for
355  // every word in the title that matched one of the query parameters. Each
356  // entry contains the start and end of the match.
357  const Snippet::MatchPositions& title_match_positions() const {
358    return title_match_positions_;
359  }
360
361  virtual void Swap(URLResult* other);
362
363 private:
364  friend class HistoryBackend;
365
366  // The time that this result corresponds to.
367  base::Time visit_time_;
368
369  // These values are typically set by HistoryBackend.
370  Snippet snippet_;
371  Snippet::MatchPositions title_match_positions_;
372
373  // We support the implicit copy constructor and operator=.
374};
375
376// QueryResults ----------------------------------------------------------------
377
378// Encapsulates the results of a history query. It supports an ordered list of
379// URLResult objects, plus an efficient way of looking up the index of each time
380// a given URL appears in those results.
381class QueryResults {
382 public:
383  typedef std::vector<URLResult*> URLResultVector;
384
385  QueryResults();
386  ~QueryResults();
387
388  // Indicates the first time that the query includes results for (queries are
389  // clipped at the beginning, so it will always include to the end of the time
390  // queried).
391  //
392  // If the number of results was clipped as a result of the max count, this
393  // will be the time of the first query returned. If there were fewer results
394  // than we were allowed to return, this represents the first date considered
395  // in the query (this will be before the first result if there was time
396  // queried with no results).
397  //
398  // TODO(brettw): bug 1203054: This field is not currently set properly! Do
399  // not use until the bug is fixed.
400  base::Time first_time_searched() const { return first_time_searched_; }
401  void set_first_time_searched(base::Time t) { first_time_searched_ = t; }
402  // Note: If you need end_time_searched, it can be added.
403
404  void set_reached_beginning(bool reached) { reached_beginning_ = reached; }
405  bool reached_beginning() { return reached_beginning_; }
406
407  size_t size() const { return results_.size(); }
408  bool empty() const { return results_.empty(); }
409
410  URLResult& operator[](size_t i) { return *results_[i]; }
411  const URLResult& operator[](size_t i) const { return *results_[i]; }
412
413  URLResultVector::const_iterator begin() const { return results_.begin(); }
414  URLResultVector::const_iterator end() const { return results_.end(); }
415  URLResultVector::const_reverse_iterator rbegin() const {
416    return results_.rbegin();
417  }
418  URLResultVector::const_reverse_iterator rend() const {
419    return results_.rend();
420  }
421
422  // Returns a pointer to the beginning of an array of all matching indices
423  // for entries with the given URL. The array will be |*num_matches| long.
424  // |num_matches| can be NULL if the caller is not interested in the number of
425  // results (commonly it will only be interested in the first one and can test
426  // the pointer for NULL).
427  //
428  // When there is no match, it will return NULL and |*num_matches| will be 0.
429  const size_t* MatchesForURL(const GURL& url, size_t* num_matches) const;
430
431  // Swaps the current result with another. This allows ownership to be
432  // efficiently transferred without copying.
433  void Swap(QueryResults* other);
434
435  // Adds the given result to the map, using swap() on the members to avoid
436  // copying (there are a lot of strings and vectors). This means the parameter
437  // object will be cleared after this call.
438  void AppendURLBySwapping(URLResult* result);
439
440  // Appends a new result set to the other. The |other| results will be
441  // destroyed because the pointer ownership will just be transferred. When
442  // |remove_dupes| is set, each URL that appears in this array will be removed
443  // from the |other| array before appending.
444  void AppendResultsBySwapping(QueryResults* other, bool remove_dupes);
445
446  // Removes all instances of the given URL from the result set.
447  void DeleteURL(const GURL& url);
448
449  // Deletes the given range of items in the result set.
450  void DeleteRange(size_t begin, size_t end);
451
452 private:
453  // Maps the given URL to a list of indices into results_ which identify each
454  // time an entry with that URL appears. Normally, each URL will have one or
455  // very few indices after it, so we optimize this to use statically allocated
456  // memory when possible.
457  typedef std::map<GURL, StackVector<size_t, 4> > URLToResultIndices;
458
459  // Inserts an entry into the |url_to_results_| map saying that the given URL
460  // is at the given index in the results_.
461  void AddURLUsageAtIndex(const GURL& url, size_t index);
462
463  // Adds |delta| to each index in url_to_results_ in the range [begin,end]
464  // (this is inclusive). This is used when inserting or deleting.
465  void AdjustResultMap(size_t begin, size_t end, ptrdiff_t delta);
466
467  base::Time first_time_searched_;
468
469  // Whether the query reaches the beginning of the database.
470  bool reached_beginning_;
471
472  // The ordered list of results. The pointers inside this are owned by this
473  // QueryResults object.
474  URLResultVector results_;
475
476  // Maps URLs to entries in results_.
477  URLToResultIndices url_to_results_;
478
479  DISALLOW_COPY_AND_ASSIGN(QueryResults);
480};
481
482// QueryOptions ----------------------------------------------------------------
483
484struct QueryOptions {
485  QueryOptions();
486
487  // The time range to search for matches in.
488  //
489  // This will match only the one recent visit of a URL.  For text search
490  // queries, if the URL was visited in the given time period, but has also been
491  // visited more recently than that, it will not be returned. When the text
492  // query is empty, this will return the most recent visit within the time
493  // range.
494  //
495  // As a special case, if both times are is_null(), then the entire database
496  // will be searched. However, if you set one, you must set the other.
497  //
498  // The beginning is inclusive and the ending is exclusive.
499  base::Time begin_time;
500  base::Time end_time;
501
502  // Sets the query time to the last |days_ago| days to the present time.
503  void SetRecentDayRange(int days_ago);
504
505  // The maximum number of results to return. The results will be sorted with
506  // the most recent first, so older results may not be returned if there is not
507  // enough room. When 0, this will return everything (the default).
508  int max_count;
509};
510
511// KeywordSearchTermVisit -----------------------------------------------------
512
513// KeywordSearchTermVisit is returned from GetMostRecentKeywordSearchTerms. It
514// gives the time and search term of the keyword visit.
515struct KeywordSearchTermVisit {
516  KeywordSearchTermVisit();
517  ~KeywordSearchTermVisit();
518
519  // The time of the visit.
520  base::Time time;
521
522  // The search term that was used.
523  string16 term;
524};
525
526// MostVisitedURL --------------------------------------------------------------
527
528// Holds the per-URL information of the most visited query.
529struct MostVisitedURL {
530  MostVisitedURL();
531  MostVisitedURL(const GURL& in_url,
532                 const GURL& in_favicon_url,
533                 const string16& in_title);
534  ~MostVisitedURL();
535
536  GURL url;
537  GURL favicon_url;
538  string16 title;
539
540  RedirectList redirects;
541
542  bool operator==(const MostVisitedURL& other) {
543    return url == other.url;
544  }
545};
546
547// Navigation -----------------------------------------------------------------
548
549// Marshalling structure for AddPage.
550class HistoryAddPageArgs
551    : public base::RefCountedThreadSafe<HistoryAddPageArgs> {
552 public:
553  HistoryAddPageArgs(const GURL& arg_url,
554                     base::Time arg_time,
555                     const void* arg_id_scope,
556                     int32 arg_page_id,
557                     const GURL& arg_referrer,
558                     const history::RedirectList& arg_redirects,
559                     PageTransition::Type arg_transition,
560                     VisitSource arg_source,
561                     bool arg_did_replace_entry);
562
563  // Returns a new HistoryAddPageArgs that is a copy of this (ref count is
564  // of course reset). Ownership of returned object passes to caller.
565  HistoryAddPageArgs* Clone() const;
566
567  GURL url;
568  base::Time time;
569
570  const void* id_scope;
571  int32 page_id;
572
573  GURL referrer;
574  history::RedirectList redirects;
575  PageTransition::Type transition;
576  VisitSource visit_source;
577  bool did_replace_entry;
578
579 private:
580  friend class base::RefCountedThreadSafe<HistoryAddPageArgs>;
581
582  ~HistoryAddPageArgs();
583
584  DISALLOW_COPY_AND_ASSIGN(HistoryAddPageArgs);
585};
586
587// TopSites -------------------------------------------------------------------
588
589typedef std::vector<MostVisitedURL> MostVisitedURLList;
590
591// Used by TopSites to store the thumbnails.
592struct Images {
593  Images();
594  ~Images();
595
596  scoped_refptr<RefCountedBytes> thumbnail;
597  ThumbnailScore thumbnail_score;
598
599  // TODO(brettw): this will eventually store the favicon.
600  // scoped_refptr<RefCountedBytes> favicon;
601};
602
603typedef std::vector<MostVisitedURL> MostVisitedURLList;
604
605struct MostVisitedURLWithRank {
606  MostVisitedURL url;
607  int rank;
608};
609
610typedef std::vector<MostVisitedURLWithRank> MostVisitedURLWithRankList;
611
612struct TopSitesDelta {
613  MostVisitedURLList deleted;
614  MostVisitedURLWithRankList added;
615  MostVisitedURLWithRankList moved;
616};
617
618typedef std::map<GURL, scoped_refptr<RefCountedBytes> > URLToThumbnailMap;
619
620// Used when migrating most visited thumbnails out of history and into topsites.
621struct ThumbnailMigration {
622  MostVisitedURLList most_visited;
623  URLToThumbnailMap url_to_thumbnail_map;
624};
625
626typedef std::map<GURL, Images> URLToImagesMap;
627
628class MostVisitedThumbnails
629    : public base::RefCountedThreadSafe<MostVisitedThumbnails> {
630 public:
631  MostVisitedThumbnails();
632
633  MostVisitedURLList most_visited;
634  URLToImagesMap url_to_images_map;
635
636 private:
637  friend class base::RefCountedThreadSafe<MostVisitedThumbnails>;
638
639  DISALLOW_COPY_AND_ASSIGN(MostVisitedThumbnails);
640};
641
642}  // namespace history
643
644#endif  // CHROME_BROWSER_HISTORY_HISTORY_TYPES_H_
645