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