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