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