Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/predictors/autocomplete_action_predictor.h" | 5 #include "chrome/browser/predictors/autocomplete_action_predictor.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/i18n/case_conversion.h" | 12 #include "base/i18n/case_conversion.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 15 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
| 16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 17 #include "chrome/browser/autocomplete/autocomplete.h" | 17 #include "chrome/browser/autocomplete/autocomplete.h" |
| 18 #include "chrome/browser/autocomplete/autocomplete_match.h" | 18 #include "chrome/browser/autocomplete/autocomplete_match.h" |
| 19 #include "chrome/browser/history/history.h" | 19 #include "chrome/browser/history/history.h" |
| 20 #include "chrome/browser/history/history_notifications.h" | 20 #include "chrome/browser/history/history_notifications.h" |
| 21 #include "chrome/browser/history/in_memory_database.h" | 21 #include "chrome/browser/history/in_memory_database.h" |
| 22 #include "chrome/browser/predictors/autocomplete_action_predictor_database.h" | 22 #include "chrome/browser/predictors/predictor_database.h" |
| 23 #include "chrome/browser/predictors/predictor_database_factory.h" | |
| 23 #include "chrome/browser/prerender/prerender_field_trial.h" | 24 #include "chrome/browser/prerender/prerender_field_trial.h" |
| 24 #include "chrome/browser/prerender/prerender_manager.h" | 25 #include "chrome/browser/prerender/prerender_manager.h" |
| 25 #include "chrome/browser/prerender/prerender_manager_factory.h" | 26 #include "chrome/browser/prerender/prerender_manager_factory.h" |
| 26 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/profiles/profile.h" |
| 27 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 28 #include "chrome/common/guid.h" | 29 #include "chrome/common/guid.h" |
| 29 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 30 #include "content/public/browser/notification_details.h" | 31 #include "content/public/browser/notification_details.h" |
| 31 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 32 #include "content/public/browser/notification_source.h" | 33 #include "content/public/browser/notification_source.h" |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 36 const float kConfidenceCutoff[] = { | 37 const float kConfidenceCutoff[] = { |
| 37 0.8f, | 38 0.8f, |
| 38 0.5f | 39 0.5f |
| 39 }; | 40 }; |
| 41 COMPILE_ASSERT(arraysize(kConfidenceCutoff) == | |
|
dominich
2012/05/08 22:49:40
nit: add a blank line before this line.
Shishir
2012/05/09 17:40:10
Done.
| |
| 42 predictors::AutocompleteActionPredictor::LAST_PREDICT_ACTION, | |
| 43 ConfidenceCutoff_count_mismatch); | |
| 40 | 44 |
| 41 const size_t kMinimumUserTextLength = 1; | 45 const size_t kMinimumUserTextLength = 1; |
| 42 const int kMinimumNumberOfHits = 3; | 46 const int kMinimumNumberOfHits = 3; |
| 43 | 47 |
| 44 COMPILE_ASSERT(arraysize(kConfidenceCutoff) == | |
| 45 AutocompleteActionPredictor::LAST_PREDICT_ACTION, | |
| 46 ConfidenceCutoff_count_mismatch); | |
| 47 | |
| 48 enum DatabaseAction { | 48 enum DatabaseAction { |
| 49 DATABASE_ACTION_ADD, | 49 DATABASE_ACTION_ADD, |
| 50 DATABASE_ACTION_UPDATE, | 50 DATABASE_ACTION_UPDATE, |
| 51 DATABASE_ACTION_DELETE_SOME, | 51 DATABASE_ACTION_DELETE_SOME, |
| 52 DATABASE_ACTION_DELETE_ALL, | 52 DATABASE_ACTION_DELETE_ALL, |
| 53 DATABASE_ACTION_COUNT | 53 DATABASE_ACTION_COUNT |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 bool IsAutocompleteMatchSearchType(const AutocompleteMatch& match) { | 56 bool IsAutocompleteMatchSearchType(const AutocompleteMatch& match) { |
| 57 switch (match.type) { | 57 switch (match.type) { |
| 58 // Matches using the user's default search engine. | 58 // Matches using the user's default search engine. |
| 59 case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: | 59 case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: |
| 60 case AutocompleteMatch::SEARCH_HISTORY: | 60 case AutocompleteMatch::SEARCH_HISTORY: |
| 61 case AutocompleteMatch::SEARCH_SUGGEST: | 61 case AutocompleteMatch::SEARCH_SUGGEST: |
| 62 // A match that uses a non-default search engine (e.g. for tab-to-search). | 62 // A match that uses a non-default search engine (e.g. for tab-to-search). |
| 63 case AutocompleteMatch::SEARCH_OTHER_ENGINE: | 63 case AutocompleteMatch::SEARCH_OTHER_ENGINE: |
| 64 return true; | 64 return true; |
| 65 | 65 |
| 66 default: | 66 default: |
| 67 return false; | 67 return false; |
| 68 } | 68 } |
| 69 } | 69 } |
| 70 | 70 |
| 71 } | 71 } // namespace |
| 72 | |
| 73 namespace predictors { | |
| 72 | 74 |
| 73 const int AutocompleteActionPredictor::kMaximumDaysToKeepEntry = 14; | 75 const int AutocompleteActionPredictor::kMaximumDaysToKeepEntry = 14; |
| 74 | 76 |
| 75 double AutocompleteActionPredictor::hit_weight_ = 1.0; | 77 double AutocompleteActionPredictor::hit_weight_ = 1.0; |
| 76 | 78 |
| 77 AutocompleteActionPredictor::AutocompleteActionPredictor(Profile* profile) | 79 AutocompleteActionPredictor::AutocompleteActionPredictor(Profile* profile) |
| 78 : profile_(profile), | 80 : profile_(profile), |
| 79 db_(new AutocompleteActionPredictorDatabase(profile)), | 81 table_(PredictorDatabaseFactory::GetForProfile( |
| 82 profile)->autocomplete_table()), | |
| 80 initialized_(false) { | 83 initialized_(false) { |
| 81 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
| 82 base::Bind(&AutocompleteActionPredictorDatabase::Initialize, db_)); | |
| 83 | |
| 84 // Request the in-memory database from the history to force it to load so it's | 84 // Request the in-memory database from the history to force it to load so it's |
| 85 // available as soon as possible. | 85 // available as soon as possible. |
| 86 HistoryService* history_service = | 86 HistoryService* history_service = |
| 87 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 87 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
| 88 if (history_service) | 88 if (history_service) |
| 89 history_service->InMemoryDatabase(); | 89 history_service->InMemoryDatabase(); |
| 90 | 90 |
| 91 // Create local caches using the database as loaded. We will garbage collect | 91 // Create local caches using the database as loaded. We will garbage collect |
| 92 // rows from the caches and the database once the history service is | 92 // rows from the caches and the database once the history service is |
| 93 // available. | 93 // available. |
| 94 std::vector<AutocompleteActionPredictorDatabase::Row>* rows = | 94 std::vector<AutocompleteActionPredictorTable::Row>* rows = |
| 95 new std::vector<AutocompleteActionPredictorDatabase::Row>(); | 95 new std::vector<AutocompleteActionPredictorTable::Row>(); |
| 96 content::BrowserThread::PostTaskAndReply( | 96 content::BrowserThread::PostTaskAndReply( |
| 97 content::BrowserThread::DB, FROM_HERE, | 97 content::BrowserThread::DB, FROM_HERE, |
| 98 base::Bind(&AutocompleteActionPredictorDatabase::GetAllRows, db_, rows), | 98 base::Bind(&AutocompleteActionPredictorTable::GetAllRows, |
| 99 table_, | |
| 100 rows), | |
| 99 base::Bind(&AutocompleteActionPredictor::CreateCaches, AsWeakPtr(), | 101 base::Bind(&AutocompleteActionPredictor::CreateCaches, AsWeakPtr(), |
| 100 base::Owned(rows))); | 102 base::Owned(rows))); |
| 101 | |
| 102 } | 103 } |
| 103 | 104 |
| 104 AutocompleteActionPredictor::~AutocompleteActionPredictor() { | 105 AutocompleteActionPredictor::~AutocompleteActionPredictor() { |
| 105 } | 106 } |
| 106 | 107 |
| 107 void AutocompleteActionPredictor::RegisterTransitionalMatches( | 108 void AutocompleteActionPredictor::RegisterTransitionalMatches( |
| 108 const string16& user_text, | 109 const string16& user_text, |
| 109 const AutocompleteResult& result) { | 110 const AutocompleteResult& result) { |
| 110 if (user_text.length() < kMinimumUserTextLength) | 111 if (user_text.length() < kMinimumUserTextLength) |
| 111 return; | 112 return; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 138 | 139 |
| 139 // Given a match, return a recommended action. | 140 // Given a match, return a recommended action. |
| 140 AutocompleteActionPredictor::Action | 141 AutocompleteActionPredictor::Action |
| 141 AutocompleteActionPredictor::RecommendAction( | 142 AutocompleteActionPredictor::RecommendAction( |
| 142 const string16& user_text, | 143 const string16& user_text, |
| 143 const AutocompleteMatch& match) const { | 144 const AutocompleteMatch& match) const { |
| 144 bool is_in_db = false; | 145 bool is_in_db = false; |
| 145 const double confidence = CalculateConfidence(user_text, match, &is_in_db); | 146 const double confidence = CalculateConfidence(user_text, match, &is_in_db); |
| 146 DCHECK(confidence >= 0.0 && confidence <= 1.0); | 147 DCHECK(confidence >= 0.0 && confidence <= 1.0); |
| 147 | 148 |
| 148 UMA_HISTOGRAM_BOOLEAN("NetworkActionPredictor.MatchIsInDb", is_in_db); | 149 UMA_HISTOGRAM_BOOLEAN("AutocompleteActionPredictor.MatchIsInDb", is_in_db); |
| 149 | 150 |
| 150 if (is_in_db) { | 151 if (is_in_db) { |
| 151 // Multiple enties with the same URL are fine as the confidence may be | 152 // Multiple enties with the same URL are fine as the confidence may be |
| 152 // different. | 153 // different. |
| 153 tracked_urls_.push_back(std::make_pair(match.destination_url, confidence)); | 154 tracked_urls_.push_back(std::make_pair(match.destination_url, confidence)); |
| 154 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.Confidence", | 155 UMA_HISTOGRAM_COUNTS_100("AutocompleteActionPredictor.Confidence", |
| 155 confidence * 100); | 156 confidence * 100); |
| 156 } | 157 } |
| 157 | 158 |
| 158 // Map the confidence to an action. | 159 // Map the confidence to an action. |
| 159 Action action = ACTION_NONE; | 160 Action action = ACTION_NONE; |
| 160 for (int i = 0; i < LAST_PREDICT_ACTION; ++i) { | 161 for (int i = 0; i < LAST_PREDICT_ACTION; ++i) { |
| 161 if (confidence >= kConfidenceCutoff[i]) { | 162 if (confidence >= kConfidenceCutoff[i]) { |
| 162 action = static_cast<Action>(i); | 163 action = static_cast<Action>(i); |
| 163 break; | 164 break; |
| 164 } | 165 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 180 } | 181 } |
| 181 | 182 |
| 182 // Return true if the suggestion type warrants a TCP/IP preconnection. | 183 // Return true if the suggestion type warrants a TCP/IP preconnection. |
| 183 // i.e., it is now quite likely that the user will select the related domain. | 184 // i.e., it is now quite likely that the user will select the related domain. |
| 184 // static | 185 // static |
| 185 bool AutocompleteActionPredictor::IsPreconnectable( | 186 bool AutocompleteActionPredictor::IsPreconnectable( |
| 186 const AutocompleteMatch& match) { | 187 const AutocompleteMatch& match) { |
| 187 return IsAutocompleteMatchSearchType(match); | 188 return IsAutocompleteMatchSearchType(match); |
| 188 } | 189 } |
| 189 | 190 |
| 190 void AutocompleteActionPredictor::Shutdown() { | |
| 191 db_->OnPredictorDestroyed(); | |
| 192 } | |
| 193 | |
| 194 void AutocompleteActionPredictor::Observe( | 191 void AutocompleteActionPredictor::Observe( |
| 195 int type, | 192 int type, |
| 196 const content::NotificationSource& source, | 193 const content::NotificationSource& source, |
| 197 const content::NotificationDetails& details) { | 194 const content::NotificationDetails& details) { |
| 198 switch (type) { | 195 switch (type) { |
| 199 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { | 196 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { |
| 200 DCHECK(initialized_); | 197 DCHECK(initialized_); |
| 201 const content::Details<const history::URLsDeletedDetails> | 198 const content::Details<const history::URLsDeletedDetails> |
| 202 urls_deleted_details = | 199 urls_deleted_details = |
| 203 content::Details<const history::URLsDeletedDetails>(details); | 200 content::Details<const history::URLsDeletedDetails>(details); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 // user is navigating to, cancel the prerender. | 252 // user is navigating to, cancel the prerender. |
| 256 prerender::PrerenderManager* prerender_manager = | 253 prerender::PrerenderManager* prerender_manager = |
| 257 prerender::PrerenderManagerFactory::GetForProfile(profile_); | 254 prerender::PrerenderManagerFactory::GetForProfile(profile_); |
| 258 // |prerender_manager| can be NULL in incognito mode or if prerendering is | 255 // |prerender_manager| can be NULL in incognito mode or if prerendering is |
| 259 // otherwise disabled. | 256 // otherwise disabled. |
| 260 if (prerender_manager && !prerender_manager->IsPrerendering(opened_url)) | 257 if (prerender_manager && !prerender_manager->IsPrerendering(opened_url)) |
| 261 prerender_manager->CancelOmniboxPrerenders(); | 258 prerender_manager->CancelOmniboxPrerenders(); |
| 262 | 259 |
| 263 const string16 lower_user_text(base::i18n::ToLower(log.text)); | 260 const string16 lower_user_text(base::i18n::ToLower(log.text)); |
| 264 | 261 |
| 265 BeginTransaction(); | |
| 266 // Traverse transitional matches for those that have a user_text that is a | 262 // Traverse transitional matches for those that have a user_text that is a |
| 267 // prefix of |lower_user_text|. | 263 // prefix of |lower_user_text|. |
| 264 std::vector<AutocompleteActionPredictorTable::Row> rows_to_add; | |
| 265 std::vector<AutocompleteActionPredictorTable::Row> rows_to_update; | |
| 266 | |
| 268 for (std::vector<TransitionalMatch>::const_iterator it = | 267 for (std::vector<TransitionalMatch>::const_iterator it = |
| 269 transitional_matches_.begin(); it != transitional_matches_.end(); | 268 transitional_matches_.begin(); it != transitional_matches_.end(); |
| 270 ++it) { | 269 ++it) { |
| 271 if (!StartsWith(lower_user_text, it->user_text, true)) | 270 if (!StartsWith(lower_user_text, it->user_text, true)) |
| 272 continue; | 271 continue; |
| 273 | 272 |
| 274 // Add entries to the database for those matches. | 273 // Add entries to the database for those matches. |
| 275 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); | 274 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); |
| 276 url_it != it->urls.end(); ++url_it) { | 275 url_it != it->urls.end(); ++url_it) { |
| 277 DCHECK(it->user_text.length() >= kMinimumUserTextLength); | 276 DCHECK(it->user_text.length() >= kMinimumUserTextLength); |
| 278 const DBCacheKey key = { it->user_text, *url_it }; | 277 const DBCacheKey key = { it->user_text, *url_it }; |
| 279 const bool is_hit = (*url_it == opened_url); | 278 const bool is_hit = (*url_it == opened_url); |
| 280 | 279 |
| 281 AutocompleteActionPredictorDatabase::Row row; | 280 AutocompleteActionPredictorTable::Row row; |
| 282 row.user_text = key.user_text; | 281 row.user_text = key.user_text; |
| 283 row.url = key.url; | 282 row.url = key.url; |
| 284 | 283 |
| 285 DBCacheMap::iterator it = db_cache_.find(key); | 284 DBCacheMap::iterator it = db_cache_.find(key); |
| 286 if (it == db_cache_.end()) { | 285 if (it == db_cache_.end()) { |
| 287 row.id = guid::GenerateGUID(); | 286 row.id = guid::GenerateGUID(); |
| 288 row.number_of_hits = is_hit ? 1 : 0; | 287 row.number_of_hits = is_hit ? 1 : 0; |
| 289 row.number_of_misses = is_hit ? 0 : 1; | 288 row.number_of_misses = is_hit ? 0 : 1; |
| 290 | 289 |
| 291 AddRow(key, row); | 290 rows_to_add.push_back(row); |
| 292 } else { | 291 } else { |
| 293 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); | 292 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); |
| 294 row.id = db_id_cache_.find(key)->second; | 293 row.id = db_id_cache_.find(key)->second; |
| 295 row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0); | 294 row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0); |
| 296 row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1); | 295 row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1); |
| 297 | 296 |
| 298 UpdateRow(it, row); | 297 rows_to_update.push_back(row); |
| 299 } | 298 } |
| 300 } | 299 } |
| 301 } | 300 } |
| 302 CommitTransaction(); | 301 if (rows_to_add.size() > 0 || rows_to_update.size() > 0) |
| 302 AddAndUpdateRows(rows_to_add, rows_to_update); | |
| 303 | 303 |
| 304 ClearTransitionalMatches(); | 304 ClearTransitionalMatches(); |
| 305 | 305 |
| 306 // Check against tracked urls and log accuracy for the confidence we | 306 // Check against tracked urls and log accuracy for the confidence we |
| 307 // predicted. | 307 // predicted. |
| 308 for (std::vector<std::pair<GURL, double> >::const_iterator it = | 308 for (std::vector<std::pair<GURL, double> >::const_iterator it = |
| 309 tracked_urls_.begin(); it != tracked_urls_.end(); | 309 tracked_urls_.begin(); it != tracked_urls_.end(); |
| 310 ++it) { | 310 ++it) { |
| 311 if (opened_url == it->first) { | 311 if (opened_url == it->first) { |
| 312 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.AccurateCount", | 312 UMA_HISTOGRAM_COUNTS_100("AutocompleteActionPredictor.AccurateCount", |
| 313 it->second * 100); | 313 it->second * 100); |
| 314 } | 314 } |
| 315 } | 315 } |
| 316 tracked_urls_.clear(); | 316 tracked_urls_.clear(); |
| 317 } | 317 } |
| 318 | 318 |
| 319 void AutocompleteActionPredictor::DeleteOldIdsFromCaches( | 319 void AutocompleteActionPredictor::DeleteOldIdsFromCaches( |
| 320 history::URLDatabase* url_db, | 320 history::URLDatabase* url_db, |
| 321 std::vector<AutocompleteActionPredictorDatabase::Row::Id>* id_list) { | 321 std::vector<AutocompleteActionPredictorTable::Row::Id>* id_list) { |
| 322 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 322 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 323 DCHECK(url_db); | 323 DCHECK(url_db); |
| 324 DCHECK(id_list); | 324 DCHECK(id_list); |
| 325 id_list->clear(); | 325 id_list->clear(); |
| 326 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 326 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
| 327 history::URLRow url_row; | 327 history::URLRow url_row; |
| 328 | 328 |
| 329 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || | 329 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || |
| 330 ((base::Time::Now() - url_row.last_visit()).InDays() > | 330 ((base::Time::Now() - url_row.last_visit()).InDays() > |
| 331 kMaximumDaysToKeepEntry)) { | 331 kMaximumDaysToKeepEntry)) { |
| 332 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | 332 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
| 333 DCHECK(id_it != db_id_cache_.end()); | 333 DCHECK(id_it != db_id_cache_.end()); |
| 334 id_list->push_back(id_it->second); | 334 id_list->push_back(id_it->second); |
| 335 db_id_cache_.erase(id_it); | 335 db_id_cache_.erase(id_it); |
| 336 db_cache_.erase(it++); | 336 db_cache_.erase(it++); |
| 337 } else { | 337 } else { |
| 338 ++it; | 338 ++it; |
| 339 } | 339 } |
| 340 } | 340 } |
| 341 } | 341 } |
| 342 | 342 |
| 343 void AutocompleteActionPredictor::DeleteOldEntries( | 343 void AutocompleteActionPredictor::DeleteOldEntries( |
| 344 history::URLDatabase* url_db) { | 344 history::URLDatabase* url_db) { |
| 345 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 345 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 346 DCHECK(!initialized_); | 346 DCHECK(!initialized_); |
| 347 | 347 |
| 348 std::vector<AutocompleteActionPredictorDatabase::Row::Id> ids_to_delete; | 348 std::vector<AutocompleteActionPredictorTable::Row::Id> ids_to_delete; |
| 349 DeleteOldIdsFromCaches(url_db, &ids_to_delete); | 349 DeleteOldIdsFromCaches(url_db, &ids_to_delete); |
| 350 | 350 |
| 351 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 351 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
| 352 base::Bind(&AutocompleteActionPredictorDatabase::DeleteRows, db_, | 352 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, |
| 353 table_, | |
| 353 ids_to_delete)); | 354 ids_to_delete)); |
| 354 | 355 |
| 355 // Register for notifications and set the |initialized_| flag. | 356 // Register for notifications and set the |initialized_| flag. |
| 356 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 357 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
| 357 content::Source<Profile>(profile_)); | 358 content::Source<Profile>(profile_)); |
| 358 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 359 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
| 359 content::Source<Profile>(profile_)); | 360 content::Source<Profile>(profile_)); |
| 360 initialized_ = true; | 361 initialized_ = true; |
| 361 } | 362 } |
| 362 | 363 |
| 363 void AutocompleteActionPredictor::CreateCaches( | 364 void AutocompleteActionPredictor::CreateCaches( |
| 364 std::vector<AutocompleteActionPredictorDatabase::Row>* rows) { | 365 std::vector<AutocompleteActionPredictorTable::Row>* rows) { |
| 365 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 366 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 366 DCHECK(!initialized_); | 367 DCHECK(!initialized_); |
| 367 DCHECK(db_cache_.empty()); | 368 DCHECK(db_cache_.empty()); |
| 368 DCHECK(db_id_cache_.empty()); | 369 DCHECK(db_id_cache_.empty()); |
| 369 | 370 |
| 370 for (std::vector<AutocompleteActionPredictorDatabase::Row>::const_iterator | 371 for (std::vector<AutocompleteActionPredictorTable::Row>::const_iterator it = |
| 371 it = rows->begin(); it != rows->end(); ++it) { | 372 rows->begin(); it != rows->end(); ++it) { |
| 372 const DBCacheKey key = { it->user_text, it->url }; | 373 const DBCacheKey key = { it->user_text, it->url }; |
| 373 const DBCacheValue value = { it->number_of_hits, it->number_of_misses }; | 374 const DBCacheValue value = { it->number_of_hits, it->number_of_misses }; |
| 374 db_cache_[key] = value; | 375 db_cache_[key] = value; |
| 375 db_id_cache_[key] = it->id; | 376 db_id_cache_[key] = it->id; |
| 376 } | 377 } |
| 377 | 378 |
| 378 // If the history service is ready, delete any old or invalid entries. | 379 // If the history service is ready, delete any old or invalid entries. |
| 379 HistoryService* history_service = | 380 HistoryService* history_service = |
| 380 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 381 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
| 381 if (!TryDeleteOldEntries(history_service)) { | 382 if (!TryDeleteOldEntries(history_service)) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 double AutocompleteActionPredictor::CalculateConfidenceForDbEntry( | 420 double AutocompleteActionPredictor::CalculateConfidenceForDbEntry( |
| 420 DBCacheMap::const_iterator iter) const { | 421 DBCacheMap::const_iterator iter) const { |
| 421 const DBCacheValue& value = iter->second; | 422 const DBCacheValue& value = iter->second; |
| 422 if (value.number_of_hits < kMinimumNumberOfHits) | 423 if (value.number_of_hits < kMinimumNumberOfHits) |
| 423 return 0.0; | 424 return 0.0; |
| 424 | 425 |
| 425 const double number_of_hits = value.number_of_hits * hit_weight_; | 426 const double number_of_hits = value.number_of_hits * hit_weight_; |
| 426 return number_of_hits / (number_of_hits + value.number_of_misses); | 427 return number_of_hits / (number_of_hits + value.number_of_misses); |
| 427 } | 428 } |
| 428 | 429 |
| 429 void AutocompleteActionPredictor::AddRow( | 430 void AutocompleteActionPredictor::AddAndUpdateRows( |
| 430 const DBCacheKey& key, | 431 const AutocompleteActionPredictorTable::Rows& rows_to_add, |
| 431 const AutocompleteActionPredictorDatabase::Row& row) { | 432 const AutocompleteActionPredictorTable::Rows& rows_to_update) { |
| 432 if (!initialized_) | 433 if (!initialized_) |
| 433 return; | 434 return; |
| 434 | 435 |
| 435 DBCacheValue value = { row.number_of_hits, row.number_of_misses }; | 436 for (AutocompleteActionPredictorTable::Rows::const_iterator it = |
| 436 db_cache_[key] = value; | 437 rows_to_add.begin(); it != rows_to_add.end(); ++it) { |
| 437 db_id_cache_[key] = row.id; | 438 const DBCacheKey key = { it->user_text, it->url }; |
| 439 DBCacheValue value = { it->number_of_hits, it->number_of_misses }; | |
| 440 | |
| 441 DCHECK(db_cache_.find(key) == db_cache_.end()); | |
| 442 | |
| 443 db_cache_[key] = value; | |
| 444 db_id_cache_[key] = it->id; | |
| 445 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
| 446 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); | |
| 447 } | |
| 448 for (AutocompleteActionPredictorTable::Rows::const_iterator it = | |
| 449 rows_to_update.begin(); it != rows_to_update.end(); ++it) { | |
| 450 const DBCacheKey key = { it->user_text, it->url }; | |
| 451 | |
| 452 DBCacheMap::iterator db_it = db_cache_.find(key); | |
| 453 DCHECK(db_it != db_cache_.end()); | |
| 454 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); | |
| 455 | |
| 456 db_it->second.number_of_hits = it->number_of_hits; | |
| 457 db_it->second.number_of_misses = it->number_of_misses; | |
| 458 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
| 459 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); | |
| 460 } | |
| 461 | |
| 438 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 462 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
| 439 base::Bind(&AutocompleteActionPredictorDatabase::AddRow, db_, row)); | 463 base::Bind(&AutocompleteActionPredictorTable::AddAndUpdateRows, |
| 440 | 464 table_, |
| 441 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 465 rows_to_add, |
| 442 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); | 466 rows_to_update)); |
| 443 } | |
| 444 | |
| 445 void AutocompleteActionPredictor::UpdateRow( | |
| 446 DBCacheMap::iterator it, | |
| 447 const AutocompleteActionPredictorDatabase::Row& row) { | |
| 448 if (!initialized_) | |
| 449 return; | |
| 450 | |
| 451 DCHECK(it != db_cache_.end()); | |
| 452 it->second.number_of_hits = row.number_of_hits; | |
| 453 it->second.number_of_misses = row.number_of_misses; | |
| 454 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
| 455 base::Bind(&AutocompleteActionPredictorDatabase::UpdateRow, db_, row)); | |
| 456 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | |
| 457 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); | |
| 458 } | 467 } |
| 459 | 468 |
| 460 void AutocompleteActionPredictor::DeleteAllRows() { | 469 void AutocompleteActionPredictor::DeleteAllRows() { |
| 461 if (!initialized_) | 470 if (!initialized_) |
| 462 return; | 471 return; |
| 463 | 472 |
| 464 db_cache_.clear(); | 473 db_cache_.clear(); |
| 465 db_id_cache_.clear(); | 474 db_id_cache_.clear(); |
| 466 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 475 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
| 467 base::Bind(&AutocompleteActionPredictorDatabase::DeleteAllRows, db_)); | 476 base::Bind(&AutocompleteActionPredictorTable::DeleteAllRows, |
| 468 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 477 table_)); |
| 478 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
| 469 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); | 479 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); |
| 470 } | 480 } |
| 471 | 481 |
| 472 void AutocompleteActionPredictor::DeleteRowsWithURLs( | 482 void AutocompleteActionPredictor::DeleteRowsWithURLs( |
| 473 const history::URLRows& rows) { | 483 const history::URLRows& rows) { |
| 474 if (!initialized_) | 484 if (!initialized_) |
| 475 return; | 485 return; |
| 476 | 486 |
| 477 std::vector<AutocompleteActionPredictorDatabase::Row::Id> id_list; | 487 std::vector<AutocompleteActionPredictorTable::Row::Id> id_list; |
| 478 | 488 |
| 479 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 489 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
| 480 if (std::find_if(rows.begin(), rows.end(), | 490 if (std::find_if(rows.begin(), rows.end(), |
| 481 history::URLRow::URLRowHasURL(it->first.url)) != rows.end()) { | 491 history::URLRow::URLRowHasURL(it->first.url)) != rows.end()) { |
| 482 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | 492 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
| 483 DCHECK(id_it != db_id_cache_.end()); | 493 DCHECK(id_it != db_id_cache_.end()); |
| 484 id_list.push_back(id_it->second); | 494 id_list.push_back(id_it->second); |
| 485 db_id_cache_.erase(id_it); | 495 db_id_cache_.erase(id_it); |
| 486 db_cache_.erase(it++); | 496 db_cache_.erase(it++); |
| 487 } else { | 497 } else { |
| 488 ++it; | 498 ++it; |
| 489 } | 499 } |
| 490 } | 500 } |
| 491 | 501 |
| 492 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 502 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
| 493 base::Bind(&AutocompleteActionPredictorDatabase::DeleteRows, | 503 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, table_, |
| 494 db_, id_list)); | 504 id_list)); |
| 495 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 505 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", |
| 496 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); | 506 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); |
| 497 } | 507 } |
| 498 | 508 |
| 499 void AutocompleteActionPredictor::BeginTransaction() { | |
| 500 if (!initialized_) | |
| 501 return; | |
| 502 | |
| 503 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
| 504 base::Bind(&AutocompleteActionPredictorDatabase::BeginTransaction, db_)); | |
| 505 } | |
| 506 | |
| 507 void AutocompleteActionPredictor::CommitTransaction() { | |
| 508 if (!initialized_) | |
| 509 return; | |
| 510 | |
| 511 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
| 512 base::Bind(&AutocompleteActionPredictorDatabase::CommitTransaction, db_)); | |
| 513 } | |
| 514 | |
| 515 AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch() { | 509 AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch() { |
| 516 } | 510 } |
| 517 | 511 |
| 518 AutocompleteActionPredictor::TransitionalMatch::~TransitionalMatch() { | 512 AutocompleteActionPredictor::TransitionalMatch::~TransitionalMatch() { |
| 519 } | 513 } |
| 514 | |
| 515 } // namespace predictors | |
| OLD | NEW |