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 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 string16& title)
    286     : url(url),
    287       title(title) {
    288 }
    289 
    290 MostVisitedURL::~MostVisitedURL() {}
    291 
    292 // FilteredURL -----------------------------------------------------------------
    293 
    294 FilteredURL::FilteredURL() : score(0.0) {}
    295 
    296 FilteredURL::FilteredURL(const PageUsageData& page_data)
    297     : url(page_data.GetURL()),
    298       title(page_data.GetTitle()),
    299       score(page_data.GetScore()) {
    300 }
    301 
    302 FilteredURL::~FilteredURL() {}
    303 
    304 // FilteredURL::ExtendedInfo ---------------------------------------------------
    305 
    306 FilteredURL::ExtendedInfo::ExtendedInfo()
    307     : total_visits(0),
    308       visits(0),
    309       duration_opened(0) {
    310 }
    311 
    312 // Images ---------------------------------------------------------------------
    313 
    314 Images::Images() {}
    315 
    316 Images::~Images() {}
    317 
    318 // TopSitesDelta --------------------------------------------------------------
    319 
    320 TopSitesDelta::TopSitesDelta() {}
    321 
    322 TopSitesDelta::~TopSitesDelta() {}
    323 
    324 // HistoryAddPageArgs ---------------------------------------------------------
    325 
    326 HistoryAddPageArgs::HistoryAddPageArgs()
    327     : id_scope(NULL),
    328       page_id(0),
    329       transition(content::PAGE_TRANSITION_LINK),
    330       visit_source(SOURCE_BROWSED),
    331       did_replace_entry(false) {}
    332 
    333 HistoryAddPageArgs::HistoryAddPageArgs(
    334     const GURL& url,
    335     base::Time time,
    336     const void* id_scope,
    337     int32 page_id,
    338     const GURL& referrer,
    339     const history::RedirectList& redirects,
    340     content::PageTransition transition,
    341     VisitSource source,
    342     bool did_replace_entry)
    343       : url(url),
    344         time(time),
    345         id_scope(id_scope),
    346         page_id(page_id),
    347         referrer(referrer),
    348         redirects(redirects),
    349         transition(transition),
    350         visit_source(source),
    351         did_replace_entry(did_replace_entry) {
    352 }
    353 
    354 HistoryAddPageArgs::~HistoryAddPageArgs() {}
    355 
    356 ThumbnailMigration::ThumbnailMigration() {}
    357 
    358 ThumbnailMigration::~ThumbnailMigration() {}
    359 
    360 MostVisitedThumbnails::MostVisitedThumbnails() {}
    361 
    362 MostVisitedThumbnails::~MostVisitedThumbnails() {}
    363 
    364 // Autocomplete thresholds -----------------------------------------------------
    365 
    366 const int kLowQualityMatchTypedLimit = 1;
    367 const int kLowQualityMatchVisitLimit = 4;
    368 const int kLowQualityMatchAgeLimitInDays = 3;
    369 
    370 base::Time AutocompleteAgeThreshold() {
    371   return (base::Time::Now() -
    372           base::TimeDelta::FromDays(kLowQualityMatchAgeLimitInDays));
    373 }
    374 
    375 bool RowQualifiesAsSignificant(const URLRow& row,
    376                                const base::Time& threshold) {
    377   const base::Time& real_threshold =
    378       threshold.is_null() ? AutocompleteAgeThreshold() : threshold;
    379   return (row.typed_count() >= kLowQualityMatchTypedLimit) ||
    380          (row.visit_count() >= kLowQualityMatchVisitLimit) ||
    381          (row.last_visit() >= real_threshold);
    382 }
    383 
    384 // IconMapping ----------------------------------------------------------------
    385 
    386 IconMapping::IconMapping()
    387     : mapping_id(0),
    388       icon_id(0),
    389       icon_type(chrome::INVALID_ICON) {
    390 }
    391 
    392 IconMapping::~IconMapping() {}
    393 
    394 // FaviconBitmapIDSize ---------------------------------------------------------
    395 
    396 FaviconBitmapIDSize::FaviconBitmapIDSize()
    397     : bitmap_id(0) {
    398 }
    399 
    400 FaviconBitmapIDSize::~FaviconBitmapIDSize() {
    401 }
    402 
    403 // FaviconBitmap --------------------------------------------------------------
    404 
    405 FaviconBitmap::FaviconBitmap()
    406     : bitmap_id(0),
    407       icon_id(0) {
    408 }
    409 
    410 FaviconBitmap::~FaviconBitmap() {
    411 }
    412 
    413 // VisitDatabaseObserver -------------------------------------------------------
    414 
    415 VisitDatabaseObserver::~VisitDatabaseObserver() {}
    416 
    417 ExpireHistoryArgs::ExpireHistoryArgs() {
    418 }
    419 
    420 ExpireHistoryArgs::~ExpireHistoryArgs() {
    421 }
    422 
    423 void ExpireHistoryArgs::SetTimeRangeForOneDay(base::Time time) {
    424   begin_time = time.LocalMidnight();
    425 
    426   // Due to DST, leap seconds, etc., the next day at midnight may be more than
    427   // 24 hours away, so add 36 hours and round back down to midnight.
    428   end_time = (begin_time + base::TimeDelta::FromHours(36)).LocalMidnight();
    429 }
    430 
    431 }  // namespace history
    432