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/autocomplete/network_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/autocomplete/network_action_predictor_database.h" | |
20 #include "chrome/browser/history/history.h" | 19 #include "chrome/browser/history/history.h" |
21 #include "chrome/browser/history/history_notifications.h" | 20 #include "chrome/browser/history/history_notifications.h" |
22 #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" |
23 #include "chrome/browser/prerender/prerender_field_trial.h" | 23 #include "chrome/browser/prerender/prerender_field_trial.h" |
24 #include "chrome/browser/prerender/prerender_manager.h" | 24 #include "chrome/browser/prerender/prerender_manager.h" |
25 #include "chrome/browser/prerender/prerender_manager_factory.h" | 25 #include "chrome/browser/prerender/prerender_manager_factory.h" |
26 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
27 #include "chrome/common/chrome_notification_types.h" | 27 #include "chrome/common/chrome_notification_types.h" |
28 #include "chrome/common/guid.h" | 28 #include "chrome/common/guid.h" |
29 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
30 #include "content/public/browser/notification_details.h" | 30 #include "content/public/browser/notification_details.h" |
31 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
32 #include "content/public/browser/notification_source.h" | 32 #include "content/public/browser/notification_source.h" |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 const float kConfidenceCutoff[] = { | 36 const float kConfidenceCutoff[] = { |
37 0.8f, | 37 0.8f, |
38 0.5f | 38 0.5f |
39 }; | 39 }; |
40 | 40 |
41 const size_t kMinimumUserTextLength = 1; | 41 const size_t kMinimumUserTextLength = 1; |
42 const int kMinimumNumberOfHits = 3; | 42 const int kMinimumNumberOfHits = 3; |
43 | 43 |
44 COMPILE_ASSERT(arraysize(kConfidenceCutoff) == | 44 COMPILE_ASSERT(arraysize(kConfidenceCutoff) == |
45 NetworkActionPredictor::LAST_PREDICT_ACTION, | 45 AutocompleteActionPredictor::LAST_PREDICT_ACTION, |
46 ConfidenceCutoff_count_mismatch); | 46 ConfidenceCutoff_count_mismatch); |
47 | 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 } |
72 | 72 |
73 const int NetworkActionPredictor::kMaximumDaysToKeepEntry = 14; | 73 const int AutocompleteActionPredictor::kMaximumDaysToKeepEntry = 14; |
74 | 74 |
75 double NetworkActionPredictor::hit_weight_ = 1.0; | 75 double AutocompleteActionPredictor::hit_weight_ = 1.0; |
76 | 76 |
77 NetworkActionPredictor::NetworkActionPredictor(Profile* profile) | 77 AutocompleteActionPredictor::AutocompleteActionPredictor(Profile* profile) |
78 : profile_(profile), | 78 : profile_(profile), |
79 db_(new NetworkActionPredictorDatabase(profile)), | 79 db_(new AutocompleteActionPredictorDatabase(profile)), |
80 initialized_(false) { | 80 initialized_(false) { |
81 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 81 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
82 base::Bind(&NetworkActionPredictorDatabase::Initialize, db_)); | 82 base::Bind(&AutocompleteActionPredictorDatabase::Initialize, db_)); |
83 | 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<NetworkActionPredictorDatabase::Row>* rows = | 94 std::vector<AutocompleteActionPredictorDatabase::Row>* rows = |
95 new std::vector<NetworkActionPredictorDatabase::Row>(); | 95 new std::vector<AutocompleteActionPredictorDatabase::Row>(); |
96 content::BrowserThread::PostTaskAndReply( | 96 content::BrowserThread::PostTaskAndReply( |
97 content::BrowserThread::DB, FROM_HERE, | 97 content::BrowserThread::DB, FROM_HERE, |
98 base::Bind(&NetworkActionPredictorDatabase::GetAllRows, db_, rows), | 98 base::Bind(&AutocompleteActionPredictorDatabase::GetAllRows, db_, rows), |
99 base::Bind(&NetworkActionPredictor::CreateCaches, AsWeakPtr(), | 99 base::Bind(&AutocompleteActionPredictor::CreateCaches, AsWeakPtr(), |
100 base::Owned(rows))); | 100 base::Owned(rows))); |
101 | 101 |
102 } | 102 } |
103 | 103 |
104 NetworkActionPredictor::~NetworkActionPredictor() { | 104 AutocompleteActionPredictor::~AutocompleteActionPredictor() { |
105 } | 105 } |
106 | 106 |
107 void NetworkActionPredictor::RegisterTransitionalMatches( | 107 void AutocompleteActionPredictor::RegisterTransitionalMatches( |
108 const string16& user_text, | 108 const string16& user_text, |
109 const AutocompleteResult& result) { | 109 const AutocompleteResult& result) { |
110 if (user_text.length() < kMinimumUserTextLength) | 110 if (user_text.length() < kMinimumUserTextLength) |
111 return; | 111 return; |
112 const string16 lower_user_text(base::i18n::ToLower(user_text)); | 112 const string16 lower_user_text(base::i18n::ToLower(user_text)); |
113 | 113 |
114 // Merge this in to an existing match if we already saw |user_text| | 114 // Merge this in to an existing match if we already saw |user_text| |
115 std::vector<TransitionalMatch>::iterator match_it = | 115 std::vector<TransitionalMatch>::iterator match_it = |
116 std::find(transitional_matches_.begin(), transitional_matches_.end(), | 116 std::find(transitional_matches_.begin(), transitional_matches_.end(), |
117 lower_user_text); | 117 lower_user_text); |
118 | 118 |
119 if (match_it == transitional_matches_.end()) { | 119 if (match_it == transitional_matches_.end()) { |
120 TransitionalMatch transitional_match; | 120 TransitionalMatch transitional_match; |
121 transitional_match.user_text = lower_user_text; | 121 transitional_match.user_text = lower_user_text; |
122 match_it = transitional_matches_.insert(transitional_matches_.end(), | 122 match_it = transitional_matches_.insert(transitional_matches_.end(), |
123 transitional_match); | 123 transitional_match); |
124 } | 124 } |
125 | 125 |
126 for (AutocompleteResult::const_iterator it = result.begin(); | 126 for (AutocompleteResult::const_iterator it = result.begin(); |
127 it != result.end(); ++it) { | 127 it != result.end(); ++it) { |
128 if (std::find(match_it->urls.begin(), match_it->urls.end(), | 128 if (std::find(match_it->urls.begin(), match_it->urls.end(), |
129 it->destination_url) == match_it->urls.end()) { | 129 it->destination_url) == match_it->urls.end()) { |
130 match_it->urls.push_back(it->destination_url); | 130 match_it->urls.push_back(it->destination_url); |
131 } | 131 } |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 void NetworkActionPredictor::ClearTransitionalMatches() { | 135 void AutocompleteActionPredictor::ClearTransitionalMatches() { |
136 transitional_matches_.clear(); | 136 transitional_matches_.clear(); |
137 } | 137 } |
138 | 138 |
139 // Given a match, return a recommended action. | 139 // Given a match, return a recommended action. |
140 NetworkActionPredictor::Action NetworkActionPredictor::RecommendAction( | 140 AutocompleteActionPredictor::Action |
141 const string16& user_text, | 141 AutocompleteActionPredictor::RecommendAction( |
142 const AutocompleteMatch& match) const { | 142 const string16& user_text, |
| 143 const AutocompleteMatch& match) const { |
143 bool is_in_db = false; | 144 bool is_in_db = false; |
144 const double confidence = CalculateConfidence(user_text, match, &is_in_db); | 145 const double confidence = CalculateConfidence(user_text, match, &is_in_db); |
145 DCHECK(confidence >= 0.0 && confidence <= 1.0); | 146 DCHECK(confidence >= 0.0 && confidence <= 1.0); |
146 | 147 |
147 UMA_HISTOGRAM_BOOLEAN("NetworkActionPredictor.MatchIsInDb", is_in_db); | 148 UMA_HISTOGRAM_BOOLEAN("NetworkActionPredictor.MatchIsInDb", is_in_db); |
148 | 149 |
149 if (is_in_db) { | 150 if (is_in_db) { |
150 // Multiple enties with the same URL are fine as the confidence may be | 151 // Multiple enties with the same URL are fine as the confidence may be |
151 // different. | 152 // different. |
152 tracked_urls_.push_back(std::make_pair(match.destination_url, confidence)); | 153 tracked_urls_.push_back(std::make_pair(match.destination_url, confidence)); |
(...skipping 21 matching lines...) Expand all Loading... |
174 !prerender::IsOmniboxEnabled(profile_))) { | 175 !prerender::IsOmniboxEnabled(profile_))) { |
175 action = ACTION_PRECONNECT; | 176 action = ACTION_PRECONNECT; |
176 } | 177 } |
177 | 178 |
178 return action; | 179 return action; |
179 } | 180 } |
180 | 181 |
181 // Return true if the suggestion type warrants a TCP/IP preconnection. | 182 // Return true if the suggestion type warrants a TCP/IP preconnection. |
182 // i.e., it is now quite likely that the user will select the related domain. | 183 // i.e., it is now quite likely that the user will select the related domain. |
183 // static | 184 // static |
184 bool NetworkActionPredictor::IsPreconnectable(const AutocompleteMatch& match) { | 185 bool AutocompleteActionPredictor::IsPreconnectable( |
| 186 const AutocompleteMatch& match) { |
185 return IsAutocompleteMatchSearchType(match); | 187 return IsAutocompleteMatchSearchType(match); |
186 } | 188 } |
187 | 189 |
188 void NetworkActionPredictor::Shutdown() { | 190 void AutocompleteActionPredictor::Shutdown() { |
189 db_->OnPredictorDestroyed(); | 191 db_->OnPredictorDestroyed(); |
190 } | 192 } |
191 | 193 |
192 void NetworkActionPredictor::Observe( | 194 void AutocompleteActionPredictor::Observe( |
193 int type, | 195 int type, |
194 const content::NotificationSource& source, | 196 const content::NotificationSource& source, |
195 const content::NotificationDetails& details) { | 197 const content::NotificationDetails& details) { |
196 switch (type) { | 198 switch (type) { |
197 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { | 199 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { |
198 DCHECK(initialized_); | 200 DCHECK(initialized_); |
199 const content::Details<const history::URLsDeletedDetails> | 201 const content::Details<const history::URLsDeletedDetails> |
200 urls_deleted_details = | 202 urls_deleted_details = |
201 content::Details<const history::URLsDeletedDetails>(details); | 203 content::Details<const history::URLsDeletedDetails>(details); |
202 if (urls_deleted_details->all_history) | 204 if (urls_deleted_details->all_history) |
(...skipping 24 matching lines...) Expand all Loading... |
227 content::Source<Profile>(profile_)); | 229 content::Source<Profile>(profile_)); |
228 break; | 230 break; |
229 } | 231 } |
230 | 232 |
231 default: | 233 default: |
232 NOTREACHED() << "Unexpected notification observed."; | 234 NOTREACHED() << "Unexpected notification observed."; |
233 break; | 235 break; |
234 } | 236 } |
235 } | 237 } |
236 | 238 |
237 void NetworkActionPredictor::OnOmniboxOpenedUrl(const AutocompleteLog& log) { | 239 void AutocompleteActionPredictor::OnOmniboxOpenedUrl( |
| 240 const AutocompleteLog& log) { |
238 if (log.text.length() < kMinimumUserTextLength) | 241 if (log.text.length() < kMinimumUserTextLength) |
239 return; | 242 return; |
240 | 243 |
241 const AutocompleteMatch& match = log.result.match_at(log.selected_index); | 244 const AutocompleteMatch& match = log.result.match_at(log.selected_index); |
242 | 245 |
243 UMA_HISTOGRAM_BOOLEAN( | 246 UMA_HISTOGRAM_BOOLEAN( |
244 StringPrintf("Prerender.OmniboxNavigationsCouldPrerender_%.1f%s", | 247 StringPrintf("Prerender.OmniboxNavigationsCouldPrerender_%.1f%s", |
245 get_hit_weight(), | 248 get_hit_weight(), |
246 prerender::PrerenderManager::GetModeString()).c_str(), | 249 prerender::PrerenderManager::GetModeString()).c_str(), |
247 prerender::IsOmniboxEnabled(profile_)); | 250 prerender::IsOmniboxEnabled(profile_)); |
(...skipping 20 matching lines...) Expand all Loading... |
268 if (!StartsWith(lower_user_text, it->user_text, true)) | 271 if (!StartsWith(lower_user_text, it->user_text, true)) |
269 continue; | 272 continue; |
270 | 273 |
271 // Add entries to the database for those matches. | 274 // Add entries to the database for those matches. |
272 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); | 275 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); |
273 url_it != it->urls.end(); ++url_it) { | 276 url_it != it->urls.end(); ++url_it) { |
274 DCHECK(it->user_text.length() >= kMinimumUserTextLength); | 277 DCHECK(it->user_text.length() >= kMinimumUserTextLength); |
275 const DBCacheKey key = { it->user_text, *url_it }; | 278 const DBCacheKey key = { it->user_text, *url_it }; |
276 const bool is_hit = (*url_it == opened_url); | 279 const bool is_hit = (*url_it == opened_url); |
277 | 280 |
278 NetworkActionPredictorDatabase::Row row; | 281 AutocompleteActionPredictorDatabase::Row row; |
279 row.user_text = key.user_text; | 282 row.user_text = key.user_text; |
280 row.url = key.url; | 283 row.url = key.url; |
281 | 284 |
282 DBCacheMap::iterator it = db_cache_.find(key); | 285 DBCacheMap::iterator it = db_cache_.find(key); |
283 if (it == db_cache_.end()) { | 286 if (it == db_cache_.end()) { |
284 row.id = guid::GenerateGUID(); | 287 row.id = guid::GenerateGUID(); |
285 row.number_of_hits = is_hit ? 1 : 0; | 288 row.number_of_hits = is_hit ? 1 : 0; |
286 row.number_of_misses = is_hit ? 0 : 1; | 289 row.number_of_misses = is_hit ? 0 : 1; |
287 | 290 |
288 AddRow(key, row); | 291 AddRow(key, row); |
(...skipping 17 matching lines...) Expand all Loading... |
306 tracked_urls_.begin(); it != tracked_urls_.end(); | 309 tracked_urls_.begin(); it != tracked_urls_.end(); |
307 ++it) { | 310 ++it) { |
308 if (opened_url == it->first) { | 311 if (opened_url == it->first) { |
309 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.AccurateCount", | 312 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.AccurateCount", |
310 it->second * 100); | 313 it->second * 100); |
311 } | 314 } |
312 } | 315 } |
313 tracked_urls_.clear(); | 316 tracked_urls_.clear(); |
314 } | 317 } |
315 | 318 |
316 void NetworkActionPredictor::DeleteOldIdsFromCaches( | 319 void AutocompleteActionPredictor::DeleteOldIdsFromCaches( |
317 history::URLDatabase* url_db, | 320 history::URLDatabase* url_db, |
318 std::vector<NetworkActionPredictorDatabase::Row::Id>* id_list) { | 321 std::vector<AutocompleteActionPredictorDatabase::Row::Id>* id_list) { |
319 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 322 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
320 DCHECK(url_db); | 323 DCHECK(url_db); |
321 DCHECK(id_list); | 324 DCHECK(id_list); |
322 id_list->clear(); | 325 id_list->clear(); |
323 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 326 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
324 history::URLRow url_row; | 327 history::URLRow url_row; |
325 | 328 |
326 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || | 329 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || |
327 ((base::Time::Now() - url_row.last_visit()).InDays() > | 330 ((base::Time::Now() - url_row.last_visit()).InDays() > |
328 kMaximumDaysToKeepEntry)) { | 331 kMaximumDaysToKeepEntry)) { |
329 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | 332 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
330 DCHECK(id_it != db_id_cache_.end()); | 333 DCHECK(id_it != db_id_cache_.end()); |
331 id_list->push_back(id_it->second); | 334 id_list->push_back(id_it->second); |
332 db_id_cache_.erase(id_it); | 335 db_id_cache_.erase(id_it); |
333 db_cache_.erase(it++); | 336 db_cache_.erase(it++); |
334 } else { | 337 } else { |
335 ++it; | 338 ++it; |
336 } | 339 } |
337 } | 340 } |
338 } | 341 } |
339 | 342 |
340 void NetworkActionPredictor::DeleteOldEntries(history::URLDatabase* url_db) { | 343 void AutocompleteActionPredictor::DeleteOldEntries( |
| 344 history::URLDatabase* url_db) { |
341 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 345 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
342 DCHECK(!initialized_); | 346 DCHECK(!initialized_); |
343 | 347 |
344 std::vector<NetworkActionPredictorDatabase::Row::Id> ids_to_delete; | 348 std::vector<AutocompleteActionPredictorDatabase::Row::Id> ids_to_delete; |
345 DeleteOldIdsFromCaches(url_db, &ids_to_delete); | 349 DeleteOldIdsFromCaches(url_db, &ids_to_delete); |
346 | 350 |
347 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 351 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
348 base::Bind(&NetworkActionPredictorDatabase::DeleteRows, db_, | 352 base::Bind(&AutocompleteActionPredictorDatabase::DeleteRows, db_, |
349 ids_to_delete)); | 353 ids_to_delete)); |
350 | 354 |
351 // Register for notifications and set the |initialized_| flag. | 355 // Register for notifications and set the |initialized_| flag. |
352 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 356 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
353 content::Source<Profile>(profile_)); | 357 content::Source<Profile>(profile_)); |
354 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 358 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
355 content::Source<Profile>(profile_)); | 359 content::Source<Profile>(profile_)); |
356 initialized_ = true; | 360 initialized_ = true; |
357 } | 361 } |
358 | 362 |
359 void NetworkActionPredictor::CreateCaches( | 363 void AutocompleteActionPredictor::CreateCaches( |
360 std::vector<NetworkActionPredictorDatabase::Row>* rows) { | 364 std::vector<AutocompleteActionPredictorDatabase::Row>* rows) { |
361 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 365 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
362 DCHECK(!initialized_); | 366 DCHECK(!initialized_); |
363 DCHECK(db_cache_.empty()); | 367 DCHECK(db_cache_.empty()); |
364 DCHECK(db_id_cache_.empty()); | 368 DCHECK(db_id_cache_.empty()); |
365 | 369 |
366 for (std::vector<NetworkActionPredictorDatabase::Row>::const_iterator it = | 370 for (std::vector<AutocompleteActionPredictorDatabase::Row>::const_iterator |
367 rows->begin(); it != rows->end(); ++it) { | 371 it = rows->begin(); it != rows->end(); ++it) { |
368 const DBCacheKey key = { it->user_text, it->url }; | 372 const DBCacheKey key = { it->user_text, it->url }; |
369 const DBCacheValue value = { it->number_of_hits, it->number_of_misses }; | 373 const DBCacheValue value = { it->number_of_hits, it->number_of_misses }; |
370 db_cache_[key] = value; | 374 db_cache_[key] = value; |
371 db_id_cache_[key] = it->id; | 375 db_id_cache_[key] = it->id; |
372 } | 376 } |
373 | 377 |
374 // If the history service is ready, delete any old or invalid entries. | 378 // If the history service is ready, delete any old or invalid entries. |
375 HistoryService* history_service = | 379 HistoryService* history_service = |
376 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 380 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
377 if (!TryDeleteOldEntries(history_service)) { | 381 if (!TryDeleteOldEntries(history_service)) { |
378 // Wait for the notification that the history service is ready and the URL | 382 // Wait for the notification that the history service is ready and the URL |
379 // DB is loaded. | 383 // DB is loaded. |
380 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, | 384 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, |
381 content::Source<Profile>(profile_)); | 385 content::Source<Profile>(profile_)); |
382 } | 386 } |
383 } | 387 } |
384 | 388 |
385 bool NetworkActionPredictor::TryDeleteOldEntries(HistoryService* service) { | 389 bool AutocompleteActionPredictor::TryDeleteOldEntries(HistoryService* service) { |
386 if (!service) | 390 if (!service) |
387 return false; | 391 return false; |
388 | 392 |
389 history::URLDatabase* url_db = service->InMemoryDatabase(); | 393 history::URLDatabase* url_db = service->InMemoryDatabase(); |
390 if (!url_db) | 394 if (!url_db) |
391 return false; | 395 return false; |
392 | 396 |
393 DeleteOldEntries(url_db); | 397 DeleteOldEntries(url_db); |
394 return true; | 398 return true; |
395 } | 399 } |
396 | 400 |
397 double NetworkActionPredictor::CalculateConfidence( | 401 double AutocompleteActionPredictor::CalculateConfidence( |
398 const string16& user_text, | 402 const string16& user_text, |
399 const AutocompleteMatch& match, | 403 const AutocompleteMatch& match, |
400 bool* is_in_db) const { | 404 bool* is_in_db) const { |
401 const DBCacheKey key = { user_text, match.destination_url }; | 405 const DBCacheKey key = { user_text, match.destination_url }; |
402 | 406 |
403 *is_in_db = false; | 407 *is_in_db = false; |
404 if (user_text.length() < kMinimumUserTextLength) | 408 if (user_text.length() < kMinimumUserTextLength) |
405 return 0.0; | 409 return 0.0; |
406 | 410 |
407 const DBCacheMap::const_iterator iter = db_cache_.find(key); | 411 const DBCacheMap::const_iterator iter = db_cache_.find(key); |
408 if (iter == db_cache_.end()) | 412 if (iter == db_cache_.end()) |
409 return 0.0; | 413 return 0.0; |
410 | 414 |
411 *is_in_db = true; | 415 *is_in_db = true; |
412 return CalculateConfidenceForDbEntry(iter); | 416 return CalculateConfidenceForDbEntry(iter); |
413 } | 417 } |
414 | 418 |
415 double NetworkActionPredictor::CalculateConfidenceForDbEntry( | 419 double AutocompleteActionPredictor::CalculateConfidenceForDbEntry( |
416 DBCacheMap::const_iterator iter) const { | 420 DBCacheMap::const_iterator iter) const { |
417 const DBCacheValue& value = iter->second; | 421 const DBCacheValue& value = iter->second; |
418 if (value.number_of_hits < kMinimumNumberOfHits) | 422 if (value.number_of_hits < kMinimumNumberOfHits) |
419 return 0.0; | 423 return 0.0; |
420 | 424 |
421 const double number_of_hits = value.number_of_hits * hit_weight_; | 425 const double number_of_hits = value.number_of_hits * hit_weight_; |
422 return number_of_hits / (number_of_hits + value.number_of_misses); | 426 return number_of_hits / (number_of_hits + value.number_of_misses); |
423 } | 427 } |
424 | 428 |
425 void NetworkActionPredictor::AddRow( | 429 void AutocompleteActionPredictor::AddRow( |
426 const DBCacheKey& key, | 430 const DBCacheKey& key, |
427 const NetworkActionPredictorDatabase::Row& row) { | 431 const AutocompleteActionPredictorDatabase::Row& row) { |
428 if (!initialized_) | 432 if (!initialized_) |
429 return; | 433 return; |
430 | 434 |
431 DBCacheValue value = { row.number_of_hits, row.number_of_misses }; | 435 DBCacheValue value = { row.number_of_hits, row.number_of_misses }; |
432 db_cache_[key] = value; | 436 db_cache_[key] = value; |
433 db_id_cache_[key] = row.id; | 437 db_id_cache_[key] = row.id; |
434 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 438 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
435 base::Bind(&NetworkActionPredictorDatabase::AddRow, db_, row)); | 439 base::Bind(&AutocompleteActionPredictorDatabase::AddRow, db_, row)); |
436 | 440 |
437 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 441 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", |
438 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); | 442 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); |
439 } | 443 } |
440 | 444 |
441 void NetworkActionPredictor::UpdateRow( | 445 void AutocompleteActionPredictor::UpdateRow( |
442 DBCacheMap::iterator it, | 446 DBCacheMap::iterator it, |
443 const NetworkActionPredictorDatabase::Row& row) { | 447 const AutocompleteActionPredictorDatabase::Row& row) { |
444 if (!initialized_) | 448 if (!initialized_) |
445 return; | 449 return; |
446 | 450 |
447 DCHECK(it != db_cache_.end()); | 451 DCHECK(it != db_cache_.end()); |
448 it->second.number_of_hits = row.number_of_hits; | 452 it->second.number_of_hits = row.number_of_hits; |
449 it->second.number_of_misses = row.number_of_misses; | 453 it->second.number_of_misses = row.number_of_misses; |
450 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 454 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
451 base::Bind(&NetworkActionPredictorDatabase::UpdateRow, db_, row)); | 455 base::Bind(&AutocompleteActionPredictorDatabase::UpdateRow, db_, row)); |
452 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 456 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", |
453 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); | 457 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); |
454 } | 458 } |
455 | 459 |
456 void NetworkActionPredictor::DeleteAllRows() { | 460 void AutocompleteActionPredictor::DeleteAllRows() { |
457 if (!initialized_) | 461 if (!initialized_) |
458 return; | 462 return; |
459 | 463 |
460 db_cache_.clear(); | 464 db_cache_.clear(); |
461 db_id_cache_.clear(); | 465 db_id_cache_.clear(); |
462 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 466 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
463 base::Bind(&NetworkActionPredictorDatabase::DeleteAllRows, db_)); | 467 base::Bind(&AutocompleteActionPredictorDatabase::DeleteAllRows, db_)); |
464 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 468 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", |
465 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); | 469 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); |
466 } | 470 } |
467 | 471 |
468 void NetworkActionPredictor::DeleteRowsWithURLs(const history::URLRows& rows) { | 472 void AutocompleteActionPredictor::DeleteRowsWithURLs( |
| 473 const history::URLRows& rows) { |
469 if (!initialized_) | 474 if (!initialized_) |
470 return; | 475 return; |
471 | 476 |
472 std::vector<NetworkActionPredictorDatabase::Row::Id> id_list; | 477 std::vector<AutocompleteActionPredictorDatabase::Row::Id> id_list; |
473 | 478 |
474 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 479 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
475 if (std::find_if(rows.begin(), rows.end(), | 480 if (std::find_if(rows.begin(), rows.end(), |
476 history::URLRow::URLRowHasURL(it->first.url)) != rows.end()) { | 481 history::URLRow::URLRowHasURL(it->first.url)) != rows.end()) { |
477 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | 482 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
478 DCHECK(id_it != db_id_cache_.end()); | 483 DCHECK(id_it != db_id_cache_.end()); |
479 id_list.push_back(id_it->second); | 484 id_list.push_back(id_it->second); |
480 db_id_cache_.erase(id_it); | 485 db_id_cache_.erase(id_it); |
481 db_cache_.erase(it++); | 486 db_cache_.erase(it++); |
482 } else { | 487 } else { |
483 ++it; | 488 ++it; |
484 } | 489 } |
485 } | 490 } |
486 | 491 |
487 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 492 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
488 base::Bind(&NetworkActionPredictorDatabase::DeleteRows, db_, id_list)); | 493 base::Bind(&AutocompleteActionPredictorDatabase::DeleteRows, |
| 494 db_, id_list)); |
489 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 495 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", |
490 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); | 496 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); |
491 } | 497 } |
492 | 498 |
493 void NetworkActionPredictor::BeginTransaction() { | 499 void AutocompleteActionPredictor::BeginTransaction() { |
494 if (!initialized_) | 500 if (!initialized_) |
495 return; | 501 return; |
496 | 502 |
497 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 503 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
498 base::Bind(&NetworkActionPredictorDatabase::BeginTransaction, db_)); | 504 base::Bind(&AutocompleteActionPredictorDatabase::BeginTransaction, db_)); |
499 } | 505 } |
500 | 506 |
501 void NetworkActionPredictor::CommitTransaction() { | 507 void AutocompleteActionPredictor::CommitTransaction() { |
502 if (!initialized_) | 508 if (!initialized_) |
503 return; | 509 return; |
504 | 510 |
505 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 511 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
506 base::Bind(&NetworkActionPredictorDatabase::CommitTransaction, db_)); | 512 base::Bind(&AutocompleteActionPredictorDatabase::CommitTransaction, db_)); |
507 } | 513 } |
508 | 514 |
509 NetworkActionPredictor::TransitionalMatch::TransitionalMatch() { | 515 AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch() { |
510 } | 516 } |
511 | 517 |
512 NetworkActionPredictor::TransitionalMatch::~TransitionalMatch() { | 518 AutocompleteActionPredictor::TransitionalMatch::~TransitionalMatch() { |
513 } | 519 } |
OLD | NEW |