Home | History | Annotate | Download | only in history
      1 // Copyright (c) 2012 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 #include "chrome/browser/history/history_types.h"
      6 
      7 #include <limits>
      8 
      9 #include "base/logging.h"
     10 #include "base/stl_util.h"
     11 #include "chrome/browser/history/page_usage_data.h"
     12 
     13 namespace history {
     14 
     15 // URLRow ----------------------------------------------------------------------
     16 
     17 URLRow::URLRow() {
     18   Initialize();
     19 }
     20 
     21 URLRow::URLRow(const GURL& url) : url_(url) {
     22   // Initialize will not set the URL, so our initialization above will stay.
     23   Initialize();
     24 }
     25 
     26 URLRow::URLRow(const GURL& url, URLID id) : url_(url) {
     27   // Initialize will not set the URL, so our initialization above will stay.
     28   Initialize();
     29   // Initialize will zero the id_, so set it here.
     30   id_ = id;
     31 }
     32 
     33 URLRow::~URLRow() {
     34 }
     35 
     36 URLRow& URLRow::operator=(const URLRow& other) {
     37   id_ = other.id_;
     38   url_ = other.url_;
     39   title_ = other.title_;
     40   visit_count_ = other.visit_count_;
     41   typed_count_ = other.typed_count_;
     42   last_visit_ = other.last_visit_;
     43   hidden_ = other.hidden_;
     44   return *this;
     45 }
     46 
     47 void URLRow::Swap(URLRow* other) {
     48   std::swap(id_, other->id_);
     49   url_.Swap(&other->url_);
     50   title_.swap(other->title_);
     51   std::swap(visit_count_, other->visit_count_);
     52   std::swap(typed_count_, other->typed_count_);
     53   std::swap(last_visit_, other->last_visit_);
     54   std::swap(hidden_, other->hidden_);
     55 }
     56 
     57 void URLRow::Initialize() {
     58   id_ = 0;
     59   visit_count_ = 0;
     60   typed_count_ = 0;
     61   last_visit_ = base::Time();
     62   hidden_ = false;
     63 }
     64 
     65 // VisitRow --------------------------------------------------------------------
     66 
     67 VisitRow::VisitRow()
     68     : visit_id(0),
     69       url_id(0),
     70       referring_visit(0),
     71       transition(content::PAGE_TRANSITION_LINK),
     72       segment_id(0) {
     73 }
     74 
     75 VisitRow::VisitRow(URLID arg_url_id,
     76                    base::Time arg_visit_time,
     77                    VisitID arg_referring_visit,
     78                    content::PageTransition arg_transition,
     79                    SegmentID arg_segment_id)
     80     : visit_id(0),
     81       url_id(arg_url_id),
     82       visit_time(arg_visit_time),
     83       referring_visit(arg_referring_visit),
     84       transition(arg_transition),
     85       segment_id(arg_segment_id) {
     86 }
     87 
     88 VisitRow::~VisitRow() {
     89 }
     90 
     91 // URLResult -------------------------------------------------------------------
     92 
     93 URLResult::URLResult()
     94     : blocked_visit_(false) {
     95 }
     96 
     97 URLResult::URLResult(const GURL& url, base::Time visit_time)
     98     : URLRow(url),
     99       visit_time_(visit_time),
    100       blocked_visit_(false) {
    101 }
    102 
    103 URLResult::URLResult(const GURL& url,
    104                      const query_parser::Snippet::MatchPositions& title_matches)
    105     : URLRow(url) {
    106   title_match_positions_ = title_matches;
    107 }
    108 URLResult::URLResult(const URLRow& url_row)
    109     : URLRow(url_row),
    110       blocked_visit_(false) {
    111 }
    112 
    113 URLResult::~URLResult() {
    114 }
    115 
    116 void URLResult::SwapResult(URLResult* other) {
    117   URLRow::Swap(other);
    118   std::swap(visit_time_, other->visit_time_);
    119   snippet_.Swap(&other->snippet_);
    120   title_match_positions_.swap(other->title_match_positions_);
    121   std::swap(blocked_visit_, other->blocked_visit_);
    122 }
    123 
    124 // static
    125 bool URLResult::CompareVisitTime(const URLResult& lhs, const URLResult& rhs) {
    126   return lhs.visit_time() > rhs.visit_time();
    127 }
    128 
    129 // QueryResults ----------------------------------------------------------------
    130 
    131 QueryResults::QueryResults() : reached_beginning_(false) {
    132 }
    133 
    134 QueryResults::~QueryResults() {}
    135 
    136 const size_t* QueryResults::MatchesForURL(const GURL& url,
    137                                           size_t* num_matches) const {
    138   URLToResultIndices::const_iterator found = url_to_results_.find(url);
    139   if (found == url_to_results_.end()) {
    140     if (num_matches)
    141       *num_matches = 0;
    142     return NULL;
    143   }
    144 
    145   // All entries in the map should have at least one index, otherwise it
    146   // shouldn't be in the map.
    147   DCHECK(!found->second->empty());
    148   if (num_matches)
    149     *num_matches = found->second->size();
    150   return &found->second->front();
    151 }
    152 
    153 void QueryResults::Swap(QueryResults* other) {
    154   std::swap(first_time_searched_, other->first_time_searched_);
    155   std::swap(reached_beginning_, other->reached_beginning_);
    156   results_.swap(other->results_);
    157   url_to_results_.swap(other->url_to_results_);
    158 }
    159 
    160 void QueryResults::AppendURLBySwapping(URLResult* result) {
    161   URLResult* new_result = new URLResult;
    162   new_result->SwapResult(result);
    163 
    164   results_.push_back(new_result);
    165   AddURLUsageAtIndex(new_result->url(), results_.size() - 1);
    166 }
    167 
    168 void QueryResults::DeleteURL(const GURL& url) {
    169   // Delete all instances of this URL. We re-query each time since each
    170   // mutation will cause the indices to change.
    171   while (const size_t* match_indices = MatchesForURL(url, NULL))
    172     DeleteRange(*match_indices, *match_indices);
    173 }
    174 
    175 void QueryResults::DeleteRange(size_t begin, size_t end) {
    176   DCHECK(begin <= end && begin < size() && end < size());
    177 
    178   // First delete the pointers in the given range and store all the URLs that
    179   // were modified. We will delete references to these later.
    180   std::set<GURL> urls_modified;
    181   for (size_t i = begin; i <= end; i++) {
    182     urls_modified.insert(results_[i]->url());
    183   }
    184 
    185   // Now just delete that range in the vector en masse (the STL ending is
    186   // exclusive, while ours is inclusive, hence the +1).
    187   results_.erase(results_.begin() + begin, results_.begin() + end + 1);
    188 
    189   // Delete the indicies referencing the deleted entries.
    190   for (std::set<GURL>::const_iterator url = urls_modified.begin();
    191        url != urls_modified.end(); ++url) {
    192     URLToResultIndices::iterator found = url_to_results_.find(*url);
    193     if (found == url_to_results_.end()) {
    194       NOTREACHED();
    195       continue;
    196     }
    197 
    198     // Need a signed loop type since we do -- which may take us to -1.
    199     for (int match = 0; match < static_cast<int>(found->second->size());
    200          match++) {
    201       if (found->second[match] >= begin && found->second[match] <= end) {
    202         // Remove this referece from the list.
    203         found->second->erase(found->second->begin() + match);
    204         match--;
    205       }
    206     }
    207 
    208     // Clear out an empty lists if we just made one.
    209     if (found->second->empty())
    210       url_to_results_.erase(found);
    211   }
    212 
    213   // Shift all other indices over to account for the removed ones.
    214   AdjustResultMap(end + 1, std::numeric_limits<size_t>::max(),
    215                   -static_cast<ptrdiff_t>(end - begin + 1));
    216 }
    217 
    218 void QueryResults::AddURLUsageAtIndex(const GURL& url, size_t index) {
    219   URLToResultIndices::iterator found = url_to_results_.find(url);
    220   if (found != url_to_results_.end()) {
    221     // The URL is already in the list, so we can just append the new index.
    222     found->second->push_back(index);
    223     return;
    224   }
    225 
    226   // Need to add a new entry for this URL.
    227   base::StackVector<size_t, 4> new_list;
    228   new_list->push_back(index);
    229   url_to_results_[url] = new_list;
    230 }
    231 
    232 void QueryResults::AdjustResultMap(size_t begin, size_t end, ptrdiff_t delta) {
    233   for (URLToResultIndices::iterator i = url_to_results_.begin();
    234        i != url_to_results_.end(); ++i) {
    235     for (size_t match = 0; match < i->second->size(); match++) {
    236       size_t match_index = i->second[match];
    237       if (match_index >= begin && match_index <= end)
    238         i->second[match] += delta;
    239     }
    240   }
    241 }
    242 
    243 // QueryOptions ----------------------------------------------------------------
    244 
    245 QueryOptions::QueryOptions()
    246     : max_count(0),
    247       duplicate_policy(QueryOptions::REMOVE_ALL_DUPLICATES) {
    248 }
    249 
    250 void QueryOptions::SetRecentDayRange(int days_ago) {
    251   end_time = base::Time::Now();
    252   begin_time = end_time - base::TimeDelta::FromDays(days_ago);
    253 }
    254 
    255 int64 QueryOptions::EffectiveBeginTime() const {
    256   return begin_time.ToInternalValue();
    257 }
    258 
    259 int64 QueryOptions::EffectiveEndTime() const {
    260   return end_time.is_null() ?
    261       std::numeric_limits<int64>::max() : end_time.ToInternalValue();
    262 }
    263 
    264 int QueryOptions::EffectiveMaxCount() const {
    265   return max_count ? max_count : std::numeric_limits<int>::max();
    266 }
    267 
    268 // KeywordSearchTermVisit -----------------------------------------------------
    269 
    270 KeywordSearchTermVisit::KeywordSearchTermVisit() : visits(0) {}
    271 
    272 KeywordSearchTermVisit::~KeywordSearchTermVisit() {}
    273 
    274 // KeywordSearchTermRow --------------------------------------------------------
    275 
    276 KeywordSearchTermRow::KeywordSearchTermRow() : keyword_id(0), url_id(0) {}
    277 
    278 KeywordSearchTermRow::~KeywordSearchTermRow() {}
    279 
    280 // MostVisitedURL --------------------------------------------------------------
    281 
    282 MostVisitedURL::MostVisitedURL() {}
    283 
    284 MostVisitedURL::MostVisitedURL(const GURL& url,
    285                                const base::string16& title)
    286     : url(url),
    287       title(title) {
    288 }
    289 
    290 MostVisitedURL::MostVisitedURL(const GURL& url,
    291                                const base::string16& title,
    292                                const base::Time& last_forced_time)
    293     : url(url),
    294       title(title),
    295       last_forced_time(last_forced_time) {
    296 }
    297 
    298 MostVisitedURL::~MostVisitedURL() {}
    299 
    300 // FilteredURL -----------------------------------------------------------------
    301 
    302 FilteredURL::FilteredURL() : score(0.0) {}
    303 
    304 FilteredURL::FilteredURL(const PageUsageData& page_data)
    305     : url(page_data.GetURL()),
    306       title(page_data.GetTitle()),
    307       score(page_data.GetScore()) {
    308 }
    309 
    310 FilteredURL::~FilteredURL() {}
    311 
    312 // FilteredURL::ExtendedInfo ---------------------------------------------------
    313 
    314 FilteredURL::ExtendedInfo::ExtendedInfo()
    315     : total_visits(0),
    316       visits(0),
    317       duration_opened(0) {
    318 }
    319 
    320 // Images ---------------------------------------------------------------------
    321 
    322 Images::Images() {}
    323 
    324 Images::~Images() {}
    325 
    326 // TopSitesDelta --------------------------------------------------------------
    327 
    328 TopSitesDelta::TopSitesDelta() {}
    329 
    330 TopSitesDelta::~TopSitesDelta() {}
    331 
    332 // HistoryAddPageArgs ---------------------------------------------------------
    333 
    334 HistoryAddPageArgs::HistoryAddPageArgs()
    335     : context_id(NULL),
    336       page_id(0),
    337       transition(content::PAGE_TRANSITION_LINK),
    338       visit_source(SOURCE_BROWSED),
    339       did_replace_entry(false) {}
    340 
    341 HistoryAddPageArgs::HistoryAddPageArgs(
    342     const GURL& url,
    343     base::Time time,
    344     ContextID context_id,
    345     int32 page_id,
    346     const GURL& referrer,
    347     const history::RedirectList& redirects,
    348     content::PageTransition transition,
    349     VisitSource source,
    350     bool did_replace_entry)
    351       : url(url),
    352         time(time),
    353         context_id(context_id),
    354         page_id(page_id),
    355         referrer(referrer),
    356         redirects(redirects),
    357         transition(transition),
    358         visit_source(source),
    359         did_replace_entry(did_replace_entry) {
    360 }
    361 
    362 HistoryAddPageArgs::~HistoryAddPageArgs() {}
    363 
    364 ThumbnailMigration::ThumbnailMigration() {}
    365 
    366 ThumbnailMigration::~ThumbnailMigration() {}
    367 
    368 MostVisitedThumbnails::MostVisitedThumbnails() {}
    369 
    370 MostVisitedThumbnails::~MostVisitedThumbnails() {}
    371 
    372 // Autocomplete thresholds -----------------------------------------------------
    373 
    374 const int kLowQualityMatchTypedLimit = 1;
    375 const int kLowQualityMatchVisitLimit = 4;
    376 const int kLowQualityMatchAgeLimitInDays = 3;
    377 
    378 base::Time AutocompleteAgeThreshold() {
    379   return (base::Time::Now() -
    380           base::TimeDelta::FromDays(kLowQualityMatchAgeLimitInDays));
    381 }
    382 
    383 bool RowQualifiesAsSignificant(const URLRow& row,
    384                                const base::Time& threshold) {
    385   const base::Time& real_threshold =
    386       threshold.is_null() ? AutocompleteAgeThreshold() : threshold;
    387   return (row.typed_count() >= kLowQualityMatchTypedLimit) ||
    388          (row.visit_count() >= kLowQualityMatchVisitLimit) ||
    389          (row.last_visit() >= real_threshold);
    390 }
    391 
    392 // IconMapping ----------------------------------------------------------------
    393 
    394 IconMapping::IconMapping()
    395     : mapping_id(0), icon_id(0), icon_type(favicon_base::INVALID_ICON) {}
    396 
    397 IconMapping::~IconMapping() {}
    398 
    399 // FaviconBitmapIDSize ---------------------------------------------------------
    400 
    401 FaviconBitmapIDSize::FaviconBitmapIDSize()
    402     : bitmap_id(0) {
    403 }
    404 
    405 FaviconBitmapIDSize::~FaviconBitmapIDSize() {
    406 }
    407 
    408 // FaviconBitmap --------------------------------------------------------------
    409 
    410 FaviconBitmap::FaviconBitmap()
    411     : bitmap_id(0),
    412       icon_id(0) {
    413 }
    414 
    415 FaviconBitmap::~FaviconBitmap() {
    416 }
    417 
    418 // VisitDatabaseObserver -------------------------------------------------------
    419 
    420 VisitDatabaseObserver::~VisitDatabaseObserver() {}
    421 
    422 ExpireHistoryArgs::ExpireHistoryArgs() {
    423 }
    424 
    425 ExpireHistoryArgs::~ExpireHistoryArgs() {
    426 }
    427 
    428 void ExpireHistoryArgs::SetTimeRangeForOneDay(base::Time time) {
    429   begin_time = time.LocalMidnight();
    430 
    431   // Due to DST, leap seconds, etc., the next day at midnight may be more than
    432   // 24 hours away, so add 36 hours and round back down to midnight.
    433   end_time = (begin_time + base::TimeDelta::FromHours(36)).LocalMidnight();
    434 }
    435 
    436 }  // namespace history
    437