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/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 |
41 const size_t kMinimumUserTextLength = 1; | 42 const size_t kMinimumUserTextLength = 1; |
42 const int kMinimumNumberOfHits = 3; | 43 const int kMinimumNumberOfHits = 3; |
43 | 44 |
44 COMPILE_ASSERT(arraysize(kConfidenceCutoff) == | 45 COMPILE_ASSERT(arraysize(kConfidenceCutoff) == |
45 NetworkActionPredictor::LAST_PREDICT_ACTION, | 46 predictors::AutocompleteActionPredictor::LAST_PREDICT_ACTION, |
46 ConfidenceCutoff_count_mismatch); | 47 ConfidenceCutoff_count_mismatch); |
47 | 48 |
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 } | 57 } // namespace |
57 | 58 |
58 const int NetworkActionPredictor::kMaximumDaysToKeepEntry = 14; | 59 namespace predictors { |
59 | 60 |
60 double NetworkActionPredictor::hit_weight_ = 1.0; | 61 const int AutocompleteActionPredictor::kMaximumDaysToKeepEntry = 14; |
61 | 62 |
62 NetworkActionPredictor::NetworkActionPredictor(Profile* profile) | 63 double AutocompleteActionPredictor::hit_weight_ = 1.0; |
64 | |
65 AutocompleteActionPredictor::AutocompleteActionPredictor(Profile* profile) | |
63 : profile_(profile), | 66 : profile_(profile), |
64 db_(new NetworkActionPredictorDatabase(profile)), | 67 db_(PredictorDatabaseFactory::GetForProfile(profile)), |
65 initialized_(false) { | 68 initialized_(false) { |
66 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
67 base::Bind(&NetworkActionPredictorDatabase::Initialize, db_)); | |
68 | |
69 // Request the in-memory database from the history to force it to load so it's | 69 // Request the in-memory database from the history to force it to load so it's |
70 // available as soon as possible. | 70 // available as soon as possible. |
71 HistoryService* history_service = | 71 HistoryService* history_service = |
72 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 72 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
73 if (history_service) | 73 if (history_service) |
74 history_service->InMemoryDatabase(); | 74 history_service->InMemoryDatabase(); |
75 | 75 |
76 // Create local caches using the database as loaded. We will garbage collect | 76 // Create local caches using the database as loaded. We will garbage collect |
77 // rows from the caches and the database once the history service is | 77 // rows from the caches and the database once the history service is |
78 // available. | 78 // available. |
79 std::vector<NetworkActionPredictorDatabase::Row>* rows = | 79 std::vector<AutocompleteActionPredictorTable::Row>* rows = |
80 new std::vector<NetworkActionPredictorDatabase::Row>(); | 80 new std::vector<AutocompleteActionPredictorTable::Row>(); |
81 content::BrowserThread::PostTaskAndReply( | 81 content::BrowserThread::PostTaskAndReply( |
82 content::BrowserThread::DB, FROM_HERE, | 82 content::BrowserThread::DB, FROM_HERE, |
83 base::Bind(&NetworkActionPredictorDatabase::GetAllRows, db_, rows), | 83 base::Bind(&AutocompleteActionPredictorTable::GetAllRows, |
84 base::Bind(&NetworkActionPredictor::CreateCaches, AsWeakPtr(), | 84 db_->autocomplete_table(), |
85 rows), | |
86 base::Bind(&AutocompleteActionPredictor::CreateCaches, AsWeakPtr(), | |
85 base::Owned(rows))); | 87 base::Owned(rows))); |
86 | |
87 } | 88 } |
88 | 89 |
89 NetworkActionPredictor::~NetworkActionPredictor() { | 90 AutocompleteActionPredictor::~AutocompleteActionPredictor() { |
90 } | 91 } |
91 | 92 |
92 void NetworkActionPredictor::RegisterTransitionalMatches( | 93 void AutocompleteActionPredictor::RegisterTransitionalMatches( |
93 const string16& user_text, | 94 const string16& user_text, |
94 const AutocompleteResult& result) { | 95 const AutocompleteResult& result) { |
95 if (user_text.length() < kMinimumUserTextLength) | 96 if (user_text.length() < kMinimumUserTextLength) |
96 return; | 97 return; |
97 const string16 lower_user_text(base::i18n::ToLower(user_text)); | 98 const string16 lower_user_text(base::i18n::ToLower(user_text)); |
98 | 99 |
99 // Merge this in to an existing match if we already saw |user_text| | 100 // Merge this in to an existing match if we already saw |user_text| |
100 std::vector<TransitionalMatch>::iterator match_it = | 101 std::vector<TransitionalMatch>::iterator match_it = |
101 std::find(transitional_matches_.begin(), transitional_matches_.end(), | 102 std::find(transitional_matches_.begin(), transitional_matches_.end(), |
102 lower_user_text); | 103 lower_user_text); |
103 | 104 |
104 if (match_it == transitional_matches_.end()) { | 105 if (match_it == transitional_matches_.end()) { |
105 TransitionalMatch transitional_match; | 106 TransitionalMatch transitional_match; |
106 transitional_match.user_text = lower_user_text; | 107 transitional_match.user_text = lower_user_text; |
107 match_it = transitional_matches_.insert(transitional_matches_.end(), | 108 match_it = transitional_matches_.insert(transitional_matches_.end(), |
108 transitional_match); | 109 transitional_match); |
109 } | 110 } |
110 | 111 |
111 for (AutocompleteResult::const_iterator it = result.begin(); | 112 for (AutocompleteResult::const_iterator it = result.begin(); |
112 it != result.end(); ++it) { | 113 it != result.end(); ++it) { |
113 if (std::find(match_it->urls.begin(), match_it->urls.end(), | 114 if (std::find(match_it->urls.begin(), match_it->urls.end(), |
114 it->destination_url) == match_it->urls.end()) { | 115 it->destination_url) == match_it->urls.end()) { |
115 match_it->urls.push_back(it->destination_url); | 116 match_it->urls.push_back(it->destination_url); |
116 } | 117 } |
117 } | 118 } |
118 } | 119 } |
119 | 120 |
120 void NetworkActionPredictor::ClearTransitionalMatches() { | 121 void AutocompleteActionPredictor::ClearTransitionalMatches() { |
121 transitional_matches_.clear(); | 122 transitional_matches_.clear(); |
122 } | 123 } |
123 | 124 |
124 // Given a match, return a recommended action. | 125 // Given a match, return a recommended action. |
125 NetworkActionPredictor::Action NetworkActionPredictor::RecommendAction( | 126 AutocompleteActionPredictor::Action |
127 AutocompleteActionPredictor::RecommendAction( | |
dominich
2012/03/06 16:42:13
i think this should be indented?
Shishir
2012/03/14 21:14:37
Done.
| |
126 const string16& user_text, | 128 const string16& user_text, |
127 const AutocompleteMatch& match) const { | 129 const AutocompleteMatch& match) const { |
128 bool is_in_db = false; | 130 bool is_in_db = false; |
129 const double confidence = CalculateConfidence(user_text, match, &is_in_db); | 131 const double confidence = CalculateConfidence(user_text, match, &is_in_db); |
130 DCHECK(confidence >= 0.0 && confidence <= 1.0); | 132 DCHECK(confidence >= 0.0 && confidence <= 1.0); |
131 | 133 |
132 UMA_HISTOGRAM_BOOLEAN("NetworkActionPredictor.MatchIsInDb", is_in_db); | 134 UMA_HISTOGRAM_BOOLEAN("AutocompleteActionPredictor.MatchIsInDb", is_in_db); |
133 | 135 |
134 if (is_in_db) { | 136 if (is_in_db) { |
135 // Multiple enties with the same URL are fine as the confidence may be | 137 // Multiple enties with the same URL are fine as the confidence may be |
136 // different. | 138 // different. |
137 tracked_urls_.push_back(std::make_pair(match.destination_url, confidence)); | 139 tracked_urls_.push_back(std::make_pair(match.destination_url, confidence)); |
138 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.Confidence", | 140 UMA_HISTOGRAM_COUNTS_100("AutocompleteActionPredictor.Confidence", |
139 confidence * 100); | 141 confidence * 100); |
140 } | 142 } |
141 | 143 |
142 // Map the confidence to an action. | 144 // Map the confidence to an action. |
143 Action action = ACTION_NONE; | 145 Action action = ACTION_NONE; |
144 for (int i = 0; i < LAST_PREDICT_ACTION; ++i) { | 146 for (int i = 0; i < LAST_PREDICT_ACTION; ++i) { |
145 if (confidence >= kConfidenceCutoff[i]) { | 147 if (confidence >= kConfidenceCutoff[i]) { |
146 action = static_cast<Action>(i); | 148 action = static_cast<Action>(i); |
147 break; | 149 break; |
148 } | 150 } |
149 } | 151 } |
150 | 152 |
151 // Downgrade prerender to preconnect if this is a search match or if omnibox | 153 // Downgrade prerender to preconnect if this is a search match or if omnibox |
152 // prerendering is disabled. | 154 // prerendering is disabled. |
153 if (action == ACTION_PRERENDER && !prerender::IsOmniboxEnabled(profile_)) | 155 if (action == ACTION_PRERENDER && !prerender::IsOmniboxEnabled(profile_)) |
154 action = ACTION_PRECONNECT; | 156 action = ACTION_PRECONNECT; |
155 | 157 |
156 return action; | 158 return action; |
157 } | 159 } |
158 | 160 |
159 // Return true if the suggestion type warrants a TCP/IP preconnection. | 161 // Return true if the suggestion type warrants a TCP/IP preconnection. |
160 // i.e., it is now quite likely that the user will select the related domain. | 162 // i.e., it is now quite likely that the user will select the related domain. |
161 // static | 163 // static |
162 bool NetworkActionPredictor::IsPreconnectable(const AutocompleteMatch& match) { | 164 bool AutocompleteActionPredictor::IsPreconnectable( |
165 const AutocompleteMatch& match) { | |
163 switch (match.type) { | 166 switch (match.type) { |
164 // Matches using the user's default search engine. | 167 // Matches using the user's default search engine. |
165 case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: | 168 case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: |
166 case AutocompleteMatch::SEARCH_HISTORY: | 169 case AutocompleteMatch::SEARCH_HISTORY: |
167 case AutocompleteMatch::SEARCH_SUGGEST: | 170 case AutocompleteMatch::SEARCH_SUGGEST: |
168 // A match that uses a non-default search engine (e.g. for tab-to-search). | 171 // A match that uses a non-default search engine (e.g. for tab-to-search). |
169 case AutocompleteMatch::SEARCH_OTHER_ENGINE: | 172 case AutocompleteMatch::SEARCH_OTHER_ENGINE: |
170 return true; | 173 return true; |
171 | 174 |
172 default: | 175 default: |
173 return false; | 176 return false; |
174 } | 177 } |
175 } | 178 } |
176 | 179 |
177 void NetworkActionPredictor::Shutdown() { | 180 void AutocompleteActionPredictor::Shutdown() { |
dominich
2012/03/06 16:42:13
note for dominic: check OnPredictorDestroyed is be
| |
178 db_->OnPredictorDestroyed(); | |
179 } | 181 } |
180 | 182 |
181 void NetworkActionPredictor::Observe( | 183 void AutocompleteActionPredictor::Observe( |
182 int type, | 184 int type, |
183 const content::NotificationSource& source, | 185 const content::NotificationSource& source, |
184 const content::NotificationDetails& details) { | 186 const content::NotificationDetails& details) { |
185 switch (type) { | 187 switch (type) { |
186 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { | 188 case chrome::NOTIFICATION_HISTORY_URLS_DELETED: { |
187 DCHECK(initialized_); | 189 DCHECK(initialized_); |
188 const content::Details<const history::URLsDeletedDetails> | 190 const content::Details<const history::URLsDeletedDetails> |
189 urls_deleted_details = | 191 urls_deleted_details = |
190 content::Details<const history::URLsDeletedDetails>(details); | 192 content::Details<const history::URLsDeletedDetails>(details); |
191 if (urls_deleted_details->all_history) | 193 if (urls_deleted_details->all_history) |
(...skipping 24 matching lines...) Expand all Loading... | |
216 content::Source<Profile>(profile_)); | 218 content::Source<Profile>(profile_)); |
217 break; | 219 break; |
218 } | 220 } |
219 | 221 |
220 default: | 222 default: |
221 NOTREACHED() << "Unexpected notification observed."; | 223 NOTREACHED() << "Unexpected notification observed."; |
222 break; | 224 break; |
223 } | 225 } |
224 } | 226 } |
225 | 227 |
226 void NetworkActionPredictor::OnOmniboxOpenedUrl(const AutocompleteLog& log) { | 228 void AutocompleteActionPredictor::OnOmniboxOpenedUrl( |
229 const AutocompleteLog& log) { | |
227 if (log.text.length() < kMinimumUserTextLength) | 230 if (log.text.length() < kMinimumUserTextLength) |
228 return; | 231 return; |
229 | 232 |
230 const AutocompleteMatch& match = log.result.match_at(log.selected_index); | 233 const AutocompleteMatch& match = log.result.match_at(log.selected_index); |
231 | 234 |
232 UMA_HISTOGRAM_BOOLEAN( | 235 UMA_HISTOGRAM_BOOLEAN( |
233 StringPrintf("Prerender.OmniboxNavigationsCouldPrerender_%.1f", | 236 StringPrintf("Prerender.OmniboxNavigationsCouldPrerender_%.1f", |
234 get_hit_weight()).c_str(), | 237 get_hit_weight()).c_str(), |
235 prerender::IsOmniboxEnabled(profile_)); | 238 prerender::IsOmniboxEnabled(profile_)); |
236 | 239 |
237 const GURL& opened_url = match.destination_url; | 240 const GURL& opened_url = match.destination_url; |
238 | 241 |
239 // If the Omnibox triggered a prerender but the URL doesn't match the one the | 242 // If the Omnibox triggered a prerender but the URL doesn't match the one the |
240 // user is navigating to, cancel the prerender. | 243 // user is navigating to, cancel the prerender. |
241 prerender::PrerenderManager* prerender_manager = | 244 prerender::PrerenderManager* prerender_manager = |
242 prerender::PrerenderManagerFactory::GetForProfile(profile_); | 245 prerender::PrerenderManagerFactory::GetForProfile(profile_); |
243 // |prerender_manager| can be NULL in incognito mode or if prerendering is | 246 // |prerender_manager| can be NULL in incognito mode or if prerendering is |
244 // otherwise disabled. | 247 // otherwise disabled. |
245 if (prerender_manager && !prerender_manager->IsPrerendering(opened_url)) | 248 if (prerender_manager && !prerender_manager->IsPrerendering(opened_url)) |
246 prerender_manager->CancelOmniboxPrerenders(); | 249 prerender_manager->CancelOmniboxPrerenders(); |
247 | 250 |
248 const string16 lower_user_text(base::i18n::ToLower(log.text)); | 251 const string16 lower_user_text(base::i18n::ToLower(log.text)); |
249 | 252 |
250 BeginTransaction(); | |
251 // Traverse transitional matches for those that have a user_text that is a | 253 // Traverse transitional matches for those that have a user_text that is a |
252 // prefix of |lower_user_text|. | 254 // prefix of |lower_user_text|. |
253 for (std::vector<TransitionalMatch>::const_iterator it = | 255 if (initialized_) { |
dominich
2012/03/06 16:42:13
before this is called there's a DCHECK that initia
Shishir
2012/03/14 21:14:37
Removed.
| |
254 transitional_matches_.begin(); it != transitional_matches_.end(); | 256 std::vector<AutocompleteActionPredictorTable::Row> rows_to_add; |
255 ++it) { | 257 std::vector<AutocompleteActionPredictorTable::Row> rows_to_update; |
256 if (!StartsWith(lower_user_text, it->user_text, true)) | |
257 continue; | |
258 | 258 |
259 // Add entries to the database for those matches. | 259 for (std::vector<TransitionalMatch>::const_iterator it = |
260 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); | 260 transitional_matches_.begin(); it != transitional_matches_.end(); |
261 url_it != it->urls.end(); ++url_it) { | 261 ++it) { |
262 DCHECK(it->user_text.length() >= kMinimumUserTextLength); | 262 if (!StartsWith(lower_user_text, it->user_text, true)) |
263 const DBCacheKey key = { it->user_text, *url_it }; | 263 continue; |
264 const bool is_hit = (*url_it == opened_url); | |
265 | 264 |
266 NetworkActionPredictorDatabase::Row row; | 265 // Add entries to the database for those matches. |
267 row.user_text = key.user_text; | 266 for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); |
268 row.url = key.url; | 267 url_it != it->urls.end(); ++url_it) { |
268 DCHECK(it->user_text.length() >= kMinimumUserTextLength); | |
269 const DBCacheKey key = { it->user_text, *url_it }; | |
270 const bool is_hit = (*url_it == opened_url); | |
269 | 271 |
270 DBCacheMap::iterator it = db_cache_.find(key); | 272 AutocompleteActionPredictorTable::Row row; |
271 if (it == db_cache_.end()) { | 273 row.user_text = key.user_text; |
272 row.id = guid::GenerateGUID(); | 274 row.url = key.url; |
273 row.number_of_hits = is_hit ? 1 : 0; | |
274 row.number_of_misses = is_hit ? 0 : 1; | |
275 | 275 |
276 AddRow(key, row); | 276 DBCacheMap::iterator it = db_cache_.find(key); |
277 } else { | 277 if (it == db_cache_.end()) { |
278 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); | 278 row.id = guid::GenerateGUID(); |
279 row.id = db_id_cache_.find(key)->second; | 279 row.number_of_hits = is_hit ? 1 : 0; |
280 row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0); | 280 row.number_of_misses = is_hit ? 0 : 1; |
281 row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1); | |
282 | 281 |
283 UpdateRow(it, row); | 282 DBCacheValue value = { row.number_of_hits, row.number_of_misses }; |
283 db_cache_[key] = value; | |
284 db_id_cache_[key] = row.id; | |
285 | |
286 rows_to_add.push_back(row); | |
287 UMA_HISTOGRAM_ENUMERATION( | |
288 "AutocompleteActionPredictor.DatabaseAction", | |
289 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); | |
290 } else { | |
291 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); | |
292 row.id = db_id_cache_.find(key)->second; | |
293 row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0); | |
294 row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1); | |
295 | |
296 it->second.number_of_hits = row.number_of_hits; | |
297 it->second.number_of_misses = row.number_of_misses; | |
298 | |
299 rows_to_update.push_back(row); | |
300 UMA_HISTOGRAM_ENUMERATION( | |
301 "AutocompleteActionPredictor.DatabaseAction", | |
302 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); | |
303 } | |
284 } | 304 } |
285 } | 305 } |
306 if (rows_to_add.size() > 0 || rows_to_update.size() > 0) | |
307 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
308 base::Bind(&AutocompleteActionPredictorTable::AddAndUpdateRows, | |
309 db_->autocomplete_table(), | |
310 rows_to_add, | |
dominich
2012/03/06 16:42:13
this will cause a full copy of the vectors to be m
Shishir
2012/03/14 21:14:37
Do these vectors get very large? If not it might b
| |
311 rows_to_update)); | |
286 } | 312 } |
287 CommitTransaction(); | |
288 | 313 |
289 ClearTransitionalMatches(); | 314 ClearTransitionalMatches(); |
290 | 315 |
291 // Check against tracked urls and log accuracy for the confidence we | 316 // Check against tracked urls and log accuracy for the confidence we |
292 // predicted. | 317 // predicted. |
293 for (std::vector<std::pair<GURL, double> >::const_iterator it = | 318 for (std::vector<std::pair<GURL, double> >::const_iterator it = |
294 tracked_urls_.begin(); it != tracked_urls_.end(); | 319 tracked_urls_.begin(); it != tracked_urls_.end(); |
295 ++it) { | 320 ++it) { |
296 if (opened_url == it->first) { | 321 if (opened_url == it->first) { |
297 UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.AccurateCount", | 322 UMA_HISTOGRAM_COUNTS_100("AutocompleteActionPredictor.AccurateCount", |
298 it->second * 100); | 323 it->second * 100); |
299 } | 324 } |
300 } | 325 } |
301 tracked_urls_.clear(); | 326 tracked_urls_.clear(); |
302 } | 327 } |
303 | 328 |
304 void NetworkActionPredictor::DeleteOldIdsFromCaches( | 329 void AutocompleteActionPredictor::DeleteOldIdsFromCaches( |
305 history::URLDatabase* url_db, | 330 history::URLDatabase* url_db, |
306 std::vector<NetworkActionPredictorDatabase::Row::Id>* id_list) { | 331 std::vector<AutocompleteActionPredictorTable::Row::Id>* id_list) { |
307 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 332 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
308 DCHECK(url_db); | 333 DCHECK(url_db); |
309 DCHECK(id_list); | 334 DCHECK(id_list); |
310 id_list->clear(); | 335 id_list->clear(); |
311 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 336 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
312 history::URLRow url_row; | 337 history::URLRow url_row; |
313 | 338 |
314 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || | 339 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || |
315 ((base::Time::Now() - url_row.last_visit()).InDays() > | 340 ((base::Time::Now() - url_row.last_visit()).InDays() > |
316 kMaximumDaysToKeepEntry)) { | 341 kMaximumDaysToKeepEntry)) { |
317 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | 342 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
318 DCHECK(id_it != db_id_cache_.end()); | 343 DCHECK(id_it != db_id_cache_.end()); |
319 id_list->push_back(id_it->second); | 344 id_list->push_back(id_it->second); |
320 db_id_cache_.erase(id_it); | 345 db_id_cache_.erase(id_it); |
321 db_cache_.erase(it++); | 346 db_cache_.erase(it++); |
322 } else { | 347 } else { |
323 ++it; | 348 ++it; |
324 } | 349 } |
325 } | 350 } |
326 } | 351 } |
327 | 352 |
328 void NetworkActionPredictor::DeleteOldEntries(history::URLDatabase* url_db) { | 353 void AutocompleteActionPredictor::DeleteOldEntries( |
354 history::URLDatabase* url_db) { | |
329 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 355 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
330 DCHECK(!initialized_); | 356 DCHECK(!initialized_); |
331 | 357 |
332 std::vector<NetworkActionPredictorDatabase::Row::Id> ids_to_delete; | 358 std::vector<AutocompleteActionPredictorTable::Row::Id> ids_to_delete; |
333 DeleteOldIdsFromCaches(url_db, &ids_to_delete); | 359 DeleteOldIdsFromCaches(url_db, &ids_to_delete); |
334 | 360 |
335 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 361 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
336 base::Bind(&NetworkActionPredictorDatabase::DeleteRows, db_, | 362 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, |
363 db_->autocomplete_table(), | |
337 ids_to_delete)); | 364 ids_to_delete)); |
338 | 365 |
339 // Register for notifications and set the |initialized_| flag. | 366 // Register for notifications and set the |initialized_| flag. |
340 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | 367 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
341 content::Source<Profile>(profile_)); | 368 content::Source<Profile>(profile_)); |
342 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | 369 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
343 content::Source<Profile>(profile_)); | 370 content::Source<Profile>(profile_)); |
344 initialized_ = true; | 371 initialized_ = true; |
345 } | 372 } |
346 | 373 |
347 void NetworkActionPredictor::CreateCaches( | 374 void AutocompleteActionPredictor::CreateCaches( |
348 std::vector<NetworkActionPredictorDatabase::Row>* rows) { | 375 std::vector<AutocompleteActionPredictorTable::Row>* rows) { |
349 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 376 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
350 DCHECK(!initialized_); | 377 DCHECK(!initialized_); |
351 DCHECK(db_cache_.empty()); | 378 DCHECK(db_cache_.empty()); |
352 DCHECK(db_id_cache_.empty()); | 379 DCHECK(db_id_cache_.empty()); |
353 | 380 |
354 for (std::vector<NetworkActionPredictorDatabase::Row>::const_iterator it = | 381 for (std::vector<AutocompleteActionPredictorTable::Row>::const_iterator it = |
355 rows->begin(); it != rows->end(); ++it) { | 382 rows->begin(); it != rows->end(); ++it) { |
356 const DBCacheKey key = { it->user_text, it->url }; | 383 const DBCacheKey key = { it->user_text, it->url }; |
357 const DBCacheValue value = { it->number_of_hits, it->number_of_misses }; | 384 const DBCacheValue value = { it->number_of_hits, it->number_of_misses }; |
358 db_cache_[key] = value; | 385 db_cache_[key] = value; |
359 db_id_cache_[key] = it->id; | 386 db_id_cache_[key] = it->id; |
360 } | 387 } |
361 | 388 |
362 // If the history service is ready, delete any old or invalid entries. | 389 // If the history service is ready, delete any old or invalid entries. |
363 HistoryService* history_service = | 390 HistoryService* history_service = |
364 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 391 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
365 if (!TryDeleteOldEntries(history_service)) { | 392 if (!TryDeleteOldEntries(history_service)) { |
366 // Wait for the notification that the history service is ready and the URL | 393 // Wait for the notification that the history service is ready and the URL |
367 // DB is loaded. | 394 // DB is loaded. |
368 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, | 395 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, |
369 content::Source<Profile>(profile_)); | 396 content::Source<Profile>(profile_)); |
370 } | 397 } |
371 } | 398 } |
372 | 399 |
373 bool NetworkActionPredictor::TryDeleteOldEntries(HistoryService* service) { | 400 bool AutocompleteActionPredictor::TryDeleteOldEntries(HistoryService* service) { |
374 if (!service) | 401 if (!service) |
375 return false; | 402 return false; |
376 | 403 |
377 history::URLDatabase* url_db = service->InMemoryDatabase(); | 404 history::URLDatabase* url_db = service->InMemoryDatabase(); |
378 if (!url_db) | 405 if (!url_db) |
379 return false; | 406 return false; |
380 | 407 |
381 DeleteOldEntries(url_db); | 408 DeleteOldEntries(url_db); |
382 return true; | 409 return true; |
383 } | 410 } |
384 | 411 |
385 double NetworkActionPredictor::CalculateConfidence( | 412 double AutocompleteActionPredictor::CalculateConfidence( |
386 const string16& user_text, | 413 const string16& user_text, |
387 const AutocompleteMatch& match, | 414 const AutocompleteMatch& match, |
388 bool* is_in_db) const { | 415 bool* is_in_db) const { |
389 const DBCacheKey key = { user_text, match.destination_url }; | 416 const DBCacheKey key = { user_text, match.destination_url }; |
390 | 417 |
391 *is_in_db = false; | 418 *is_in_db = false; |
392 if (user_text.length() < kMinimumUserTextLength) | 419 if (user_text.length() < kMinimumUserTextLength) |
393 return 0.0; | 420 return 0.0; |
394 | 421 |
395 const DBCacheMap::const_iterator iter = db_cache_.find(key); | 422 const DBCacheMap::const_iterator iter = db_cache_.find(key); |
396 if (iter == db_cache_.end()) | 423 if (iter == db_cache_.end()) |
397 return 0.0; | 424 return 0.0; |
398 | 425 |
399 *is_in_db = true; | 426 *is_in_db = true; |
400 return CalculateConfidenceForDbEntry(iter); | 427 return CalculateConfidenceForDbEntry(iter); |
401 } | 428 } |
402 | 429 |
403 double NetworkActionPredictor::CalculateConfidenceForDbEntry( | 430 double AutocompleteActionPredictor::CalculateConfidenceForDbEntry( |
404 DBCacheMap::const_iterator iter) const { | 431 DBCacheMap::const_iterator iter) const { |
405 const DBCacheValue& value = iter->second; | 432 const DBCacheValue& value = iter->second; |
406 if (value.number_of_hits < kMinimumNumberOfHits) | 433 if (value.number_of_hits < kMinimumNumberOfHits) |
407 return 0.0; | 434 return 0.0; |
408 | 435 |
409 const double number_of_hits = value.number_of_hits * hit_weight_; | 436 const double number_of_hits = value.number_of_hits * hit_weight_; |
410 return number_of_hits / (number_of_hits + value.number_of_misses); | 437 return number_of_hits / (number_of_hits + value.number_of_misses); |
411 } | 438 } |
412 | 439 |
413 void NetworkActionPredictor::AddRow( | 440 void AutocompleteActionPredictor::AddRow( |
414 const DBCacheKey& key, | 441 const DBCacheKey& key, |
415 const NetworkActionPredictorDatabase::Row& row) { | 442 const AutocompleteActionPredictorTable::Row& row) { |
416 if (!initialized_) | 443 if (!initialized_) |
417 return; | 444 return; |
418 | 445 |
419 DBCacheValue value = { row.number_of_hits, row.number_of_misses }; | 446 DBCacheValue value = { row.number_of_hits, row.number_of_misses }; |
420 db_cache_[key] = value; | 447 db_cache_[key] = value; |
421 db_id_cache_[key] = row.id; | 448 db_id_cache_[key] = row.id; |
422 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 449 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
423 base::Bind(&NetworkActionPredictorDatabase::AddRow, db_, row)); | 450 base::Bind(&AutocompleteActionPredictorTable::AddRow, |
451 db_->autocomplete_table(), | |
452 row)); | |
424 | 453 |
425 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 454 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", |
426 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); | 455 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); |
427 } | 456 } |
428 | 457 |
429 void NetworkActionPredictor::UpdateRow( | 458 void AutocompleteActionPredictor::UpdateRow( |
430 DBCacheMap::iterator it, | 459 DBCacheMap::iterator it, |
431 const NetworkActionPredictorDatabase::Row& row) { | 460 const AutocompleteActionPredictorTable::Row& row) { |
432 if (!initialized_) | 461 if (!initialized_) |
433 return; | 462 return; |
434 | 463 |
435 DCHECK(it != db_cache_.end()); | 464 DCHECK(it != db_cache_.end()); |
436 it->second.number_of_hits = row.number_of_hits; | 465 it->second.number_of_hits = row.number_of_hits; |
437 it->second.number_of_misses = row.number_of_misses; | 466 it->second.number_of_misses = row.number_of_misses; |
438 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 467 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
439 base::Bind(&NetworkActionPredictorDatabase::UpdateRow, db_, row)); | 468 base::Bind(&AutocompleteActionPredictorTable::UpdateRow, |
440 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 469 db_->autocomplete_table(), |
470 row)); | |
471 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
441 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); | 472 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); |
442 } | 473 } |
443 | 474 |
444 void NetworkActionPredictor::DeleteAllRows() { | 475 void AutocompleteActionPredictor::DeleteAllRows() { |
445 if (!initialized_) | 476 if (!initialized_) |
446 return; | 477 return; |
447 | 478 |
448 db_cache_.clear(); | 479 db_cache_.clear(); |
449 db_id_cache_.clear(); | 480 db_id_cache_.clear(); |
450 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 481 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
451 base::Bind(&NetworkActionPredictorDatabase::DeleteAllRows, db_)); | 482 base::Bind(&AutocompleteActionPredictorTable::DeleteAllRows, |
452 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 483 db_->autocomplete_table())); |
484 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
453 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); | 485 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); |
454 } | 486 } |
455 | 487 |
456 void NetworkActionPredictor::DeleteRowsWithURLs(const std::set<GURL>& urls) { | 488 void AutocompleteActionPredictor::DeleteRowsWithURLs( |
489 const std::set<GURL>& urls) { | |
457 if (!initialized_) | 490 if (!initialized_) |
458 return; | 491 return; |
459 | 492 |
460 std::vector<NetworkActionPredictorDatabase::Row::Id> id_list; | 493 std::vector<AutocompleteActionPredictorTable::Row::Id> id_list; |
461 | 494 |
462 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | 495 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
463 if (urls.find(it->first.url) != urls.end()) { | 496 if (urls.find(it->first.url) != urls.end()) { |
464 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | 497 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
465 DCHECK(id_it != db_id_cache_.end()); | 498 DCHECK(id_it != db_id_cache_.end()); |
466 id_list.push_back(id_it->second); | 499 id_list.push_back(id_it->second); |
467 db_id_cache_.erase(id_it); | 500 db_id_cache_.erase(id_it); |
468 db_cache_.erase(it++); | 501 db_cache_.erase(it++); |
469 } else { | 502 } else { |
470 ++it; | 503 ++it; |
471 } | 504 } |
472 } | 505 } |
473 | 506 |
474 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 507 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
475 base::Bind(&NetworkActionPredictorDatabase::DeleteRows, db_, id_list)); | 508 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, |
476 UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction", | 509 db_->autocomplete_table(), |
dominich
2012/03/06 16:42:13
is it worth storing the reference to the table ins
Shishir
2012/03/14 21:14:37
We didnt want to do that earlier since the table w
| |
510 id_list)); | |
511 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
477 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); | 512 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); |
478 } | 513 } |
479 | 514 |
480 void NetworkActionPredictor::BeginTransaction() { | 515 AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch() { |
481 if (!initialized_) | |
482 return; | |
483 | |
484 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
485 base::Bind(&NetworkActionPredictorDatabase::BeginTransaction, db_)); | |
486 } | 516 } |
487 | 517 |
488 void NetworkActionPredictor::CommitTransaction() { | 518 AutocompleteActionPredictor::TransitionalMatch::~TransitionalMatch() { |
489 if (!initialized_) | |
490 return; | |
491 | |
492 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
493 base::Bind(&NetworkActionPredictorDatabase::CommitTransaction, db_)); | |
494 } | 519 } |
495 | 520 |
496 NetworkActionPredictor::TransitionalMatch::TransitionalMatch() { | 521 } // namespace predictors |
497 } | |
498 | |
499 NetworkActionPredictor::TransitionalMatch::~TransitionalMatch() { | |
500 } | |
OLD | NEW |