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 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 content::Source<Profile>(profile_)); | 225 content::Source<Profile>(profile_)); |
226 break; | 226 break; |
227 } | 227 } |
228 | 228 |
229 default: | 229 default: |
230 NOTREACHED() << "Unexpected notification observed."; | 230 NOTREACHED() << "Unexpected notification observed."; |
231 break; | 231 break; |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
| 235 void AutocompleteActionPredictor::DeleteAllRows() { |
| 236 if (!initialized_) |
| 237 return; |
| 238 |
| 239 db_cache_.clear(); |
| 240 db_id_cache_.clear(); |
| 241 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
| 242 base::Bind(&AutocompleteActionPredictorTable::DeleteAllRows, |
| 243 table_)); |
| 244 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", |
| 245 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); |
| 246 } |
| 247 |
| 248 void AutocompleteActionPredictor::DeleteRowsWithURLs( |
| 249 const history::URLRows& rows) { |
| 250 if (!initialized_) |
| 251 return; |
| 252 |
| 253 std::vector<AutocompleteActionPredictorTable::Row::Id> id_list; |
| 254 |
| 255 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
| 256 if (std::find_if(rows.begin(), rows.end(), |
| 257 history::URLRow::URLRowHasURL(it->first.url)) != rows.end()) { |
| 258 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
| 259 DCHECK(id_it != db_id_cache_.end()); |
| 260 id_list.push_back(id_it->second); |
| 261 db_id_cache_.erase(id_it); |
| 262 db_cache_.erase(it++); |
| 263 } else { |
| 264 ++it; |
| 265 } |
| 266 } |
| 267 |
| 268 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
| 269 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, table_, |
| 270 id_list)); |
| 271 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", |
| 272 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); |
| 273 } |
| 274 |
235 void AutocompleteActionPredictor::OnOmniboxOpenedUrl( | 275 void AutocompleteActionPredictor::OnOmniboxOpenedUrl( |
236 const AutocompleteLog& log) { | 276 const AutocompleteLog& log) { |
237 if (log.text.length() < kMinimumUserTextLength) | 277 if (log.text.length() < kMinimumUserTextLength) |
238 return; | 278 return; |
239 | 279 |
240 const AutocompleteMatch& match = log.result.match_at(log.selected_index); | 280 const AutocompleteMatch& match = log.result.match_at(log.selected_index); |
241 | 281 |
242 UMA_HISTOGRAM_BOOLEAN( | 282 UMA_HISTOGRAM_BOOLEAN( |
243 StringPrintf("Prerender.OmniboxNavigationsCouldPrerender%s", | 283 StringPrintf("Prerender.OmniboxNavigationsCouldPrerender%s", |
244 prerender::PrerenderManager::GetModeString()).c_str(), | 284 prerender::PrerenderManager::GetModeString()).c_str(), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 tracked_urls_.begin(); it != tracked_urls_.end(); | 347 tracked_urls_.begin(); it != tracked_urls_.end(); |
308 ++it) { | 348 ++it) { |
309 if (opened_url == it->first) { | 349 if (opened_url == it->first) { |
310 UMA_HISTOGRAM_COUNTS_100("AutocompleteActionPredictor.AccurateCount", | 350 UMA_HISTOGRAM_COUNTS_100("AutocompleteActionPredictor.AccurateCount", |
311 it->second * 100); | 351 it->second * 100); |
312 } | 352 } |
313 } | 353 } |
314 tracked_urls_.clear(); | 354 tracked_urls_.clear(); |
315 } | 355 } |
316 | 356 |
317 void AutocompleteActionPredictor::DeleteOldIdsFromCaches( | 357 void AutocompleteActionPredictor::AddAndUpdateRows( |
318 history::URLDatabase* url_db, | 358 const AutocompleteActionPredictorTable::Rows& rows_to_add, |
319 std::vector<AutocompleteActionPredictorTable::Row::Id>* id_list) { | 359 const AutocompleteActionPredictorTable::Rows& rows_to_update) { |
320 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 360 if (!initialized_) |
321 DCHECK(url_db); | 361 return; |
322 DCHECK(id_list); | |
323 id_list->clear(); | |
324 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | |
325 history::URLRow url_row; | |
326 | 362 |
327 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || | 363 for (AutocompleteActionPredictorTable::Rows::const_iterator it = |
328 ((base::Time::Now() - url_row.last_visit()).InDays() > | 364 rows_to_add.begin(); it != rows_to_add.end(); ++it) { |
329 kMaximumDaysToKeepEntry)) { | 365 const DBCacheKey key = { it->user_text, it->url }; |
330 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | 366 DBCacheValue value = { it->number_of_hits, it->number_of_misses }; |
331 DCHECK(id_it != db_id_cache_.end()); | 367 |
332 id_list->push_back(id_it->second); | 368 DCHECK(db_cache_.find(key) == db_cache_.end()); |
333 db_id_cache_.erase(id_it); | 369 |
334 db_cache_.erase(it++); | 370 db_cache_[key] = value; |
335 } else { | 371 db_id_cache_[key] = it->id; |
336 ++it; | 372 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", |
337 } | 373 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); |
338 } | 374 } |
339 } | 375 for (AutocompleteActionPredictorTable::Rows::const_iterator it = |
| 376 rows_to_update.begin(); it != rows_to_update.end(); ++it) { |
| 377 const DBCacheKey key = { it->user_text, it->url }; |
340 | 378 |
341 void AutocompleteActionPredictor::DeleteOldEntries( | 379 DBCacheMap::iterator db_it = db_cache_.find(key); |
342 history::URLDatabase* url_db) { | 380 DCHECK(db_it != db_cache_.end()); |
343 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 381 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); |
344 DCHECK(!initialized_); | |
345 | 382 |
346 std::vector<AutocompleteActionPredictorTable::Row::Id> ids_to_delete; | 383 db_it->second.number_of_hits = it->number_of_hits; |
347 DeleteOldIdsFromCaches(url_db, &ids_to_delete); | 384 db_it->second.number_of_misses = it->number_of_misses; |
| 385 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", |
| 386 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); |
| 387 } |
348 | 388 |
349 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | 389 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
350 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, | 390 base::Bind(&AutocompleteActionPredictorTable::AddAndUpdateRows, |
351 table_, | 391 table_, |
352 ids_to_delete)); | 392 rows_to_add, |
353 | 393 rows_to_update)); |
354 // Register for notifications and set the |initialized_| flag. | |
355 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, | |
356 content::Source<Profile>(profile_)); | |
357 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, | |
358 content::Source<Profile>(profile_)); | |
359 initialized_ = true; | |
360 } | 394 } |
361 | 395 |
362 void AutocompleteActionPredictor::CreateCaches( | 396 void AutocompleteActionPredictor::CreateCaches( |
363 std::vector<AutocompleteActionPredictorTable::Row>* rows) { | 397 std::vector<AutocompleteActionPredictorTable::Row>* rows) { |
364 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 398 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
365 DCHECK(!initialized_); | 399 DCHECK(!initialized_); |
366 DCHECK(db_cache_.empty()); | 400 DCHECK(db_cache_.empty()); |
367 DCHECK(db_id_cache_.empty()); | 401 DCHECK(db_id_cache_.empty()); |
368 | 402 |
369 for (std::vector<AutocompleteActionPredictorTable::Row>::const_iterator it = | 403 for (std::vector<AutocompleteActionPredictorTable::Row>::const_iterator it = |
(...skipping 20 matching lines...) Expand all Loading... |
390 return false; | 424 return false; |
391 | 425 |
392 history::URLDatabase* url_db = service->InMemoryDatabase(); | 426 history::URLDatabase* url_db = service->InMemoryDatabase(); |
393 if (!url_db) | 427 if (!url_db) |
394 return false; | 428 return false; |
395 | 429 |
396 DeleteOldEntries(url_db); | 430 DeleteOldEntries(url_db); |
397 return true; | 431 return true; |
398 } | 432 } |
399 | 433 |
| 434 void AutocompleteActionPredictor::DeleteOldEntries( |
| 435 history::URLDatabase* url_db) { |
| 436 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 437 DCHECK(!initialized_); |
| 438 |
| 439 std::vector<AutocompleteActionPredictorTable::Row::Id> ids_to_delete; |
| 440 DeleteOldIdsFromCaches(url_db, &ids_to_delete); |
| 441 |
| 442 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, |
| 443 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, |
| 444 table_, |
| 445 ids_to_delete)); |
| 446 |
| 447 // Register for notifications and set the |initialized_| flag. |
| 448 notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL, |
| 449 content::Source<Profile>(profile_)); |
| 450 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, |
| 451 content::Source<Profile>(profile_)); |
| 452 initialized_ = true; |
| 453 } |
| 454 |
| 455 void AutocompleteActionPredictor::DeleteOldIdsFromCaches( |
| 456 history::URLDatabase* url_db, |
| 457 std::vector<AutocompleteActionPredictorTable::Row::Id>* id_list) { |
| 458 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 459 DCHECK(url_db); |
| 460 DCHECK(id_list); |
| 461 id_list->clear(); |
| 462 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { |
| 463 history::URLRow url_row; |
| 464 |
| 465 if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) || |
| 466 ((base::Time::Now() - url_row.last_visit()).InDays() > |
| 467 kMaximumDaysToKeepEntry)) { |
| 468 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); |
| 469 DCHECK(id_it != db_id_cache_.end()); |
| 470 id_list->push_back(id_it->second); |
| 471 db_id_cache_.erase(id_it); |
| 472 db_cache_.erase(it++); |
| 473 } else { |
| 474 ++it; |
| 475 } |
| 476 } |
| 477 } |
| 478 |
400 double AutocompleteActionPredictor::CalculateConfidence( | 479 double AutocompleteActionPredictor::CalculateConfidence( |
401 const string16& user_text, | 480 const string16& user_text, |
402 const AutocompleteMatch& match, | 481 const AutocompleteMatch& match, |
403 bool* is_in_db) const { | 482 bool* is_in_db) const { |
404 const DBCacheKey key = { user_text, match.destination_url }; | 483 const DBCacheKey key = { user_text, match.destination_url }; |
405 | 484 |
406 *is_in_db = false; | 485 *is_in_db = false; |
407 if (user_text.length() < kMinimumUserTextLength) | 486 if (user_text.length() < kMinimumUserTextLength) |
408 return 0.0; | 487 return 0.0; |
409 | 488 |
410 const DBCacheMap::const_iterator iter = db_cache_.find(key); | 489 const DBCacheMap::const_iterator iter = db_cache_.find(key); |
411 if (iter == db_cache_.end()) | 490 if (iter == db_cache_.end()) |
412 return 0.0; | 491 return 0.0; |
413 | 492 |
414 *is_in_db = true; | 493 *is_in_db = true; |
415 return CalculateConfidenceForDbEntry(iter); | 494 return CalculateConfidenceForDbEntry(iter); |
416 } | 495 } |
417 | 496 |
418 double AutocompleteActionPredictor::CalculateConfidenceForDbEntry( | 497 double AutocompleteActionPredictor::CalculateConfidenceForDbEntry( |
419 DBCacheMap::const_iterator iter) const { | 498 DBCacheMap::const_iterator iter) const { |
420 const DBCacheValue& value = iter->second; | 499 const DBCacheValue& value = iter->second; |
421 if (value.number_of_hits < kMinimumNumberOfHits) | 500 if (value.number_of_hits < kMinimumNumberOfHits) |
422 return 0.0; | 501 return 0.0; |
423 | 502 |
424 const double number_of_hits = static_cast<double>(value.number_of_hits); | 503 const double number_of_hits = static_cast<double>(value.number_of_hits); |
425 return number_of_hits / (number_of_hits + value.number_of_misses); | 504 return number_of_hits / (number_of_hits + value.number_of_misses); |
426 } | 505 } |
427 | 506 |
428 void AutocompleteActionPredictor::AddAndUpdateRows( | |
429 const AutocompleteActionPredictorTable::Rows& rows_to_add, | |
430 const AutocompleteActionPredictorTable::Rows& rows_to_update) { | |
431 if (!initialized_) | |
432 return; | |
433 | |
434 for (AutocompleteActionPredictorTable::Rows::const_iterator it = | |
435 rows_to_add.begin(); it != rows_to_add.end(); ++it) { | |
436 const DBCacheKey key = { it->user_text, it->url }; | |
437 DBCacheValue value = { it->number_of_hits, it->number_of_misses }; | |
438 | |
439 DCHECK(db_cache_.find(key) == db_cache_.end()); | |
440 | |
441 db_cache_[key] = value; | |
442 db_id_cache_[key] = it->id; | |
443 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
444 DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT); | |
445 } | |
446 for (AutocompleteActionPredictorTable::Rows::const_iterator it = | |
447 rows_to_update.begin(); it != rows_to_update.end(); ++it) { | |
448 const DBCacheKey key = { it->user_text, it->url }; | |
449 | |
450 DBCacheMap::iterator db_it = db_cache_.find(key); | |
451 DCHECK(db_it != db_cache_.end()); | |
452 DCHECK(db_id_cache_.find(key) != db_id_cache_.end()); | |
453 | |
454 db_it->second.number_of_hits = it->number_of_hits; | |
455 db_it->second.number_of_misses = it->number_of_misses; | |
456 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
457 DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT); | |
458 } | |
459 | |
460 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
461 base::Bind(&AutocompleteActionPredictorTable::AddAndUpdateRows, | |
462 table_, | |
463 rows_to_add, | |
464 rows_to_update)); | |
465 } | |
466 | |
467 void AutocompleteActionPredictor::DeleteAllRows() { | |
468 if (!initialized_) | |
469 return; | |
470 | |
471 db_cache_.clear(); | |
472 db_id_cache_.clear(); | |
473 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
474 base::Bind(&AutocompleteActionPredictorTable::DeleteAllRows, | |
475 table_)); | |
476 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
477 DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT); | |
478 } | |
479 | |
480 void AutocompleteActionPredictor::DeleteRowsWithURLs( | |
481 const history::URLRows& rows) { | |
482 if (!initialized_) | |
483 return; | |
484 | |
485 std::vector<AutocompleteActionPredictorTable::Row::Id> id_list; | |
486 | |
487 for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) { | |
488 if (std::find_if(rows.begin(), rows.end(), | |
489 history::URLRow::URLRowHasURL(it->first.url)) != rows.end()) { | |
490 const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first); | |
491 DCHECK(id_it != db_id_cache_.end()); | |
492 id_list.push_back(id_it->second); | |
493 db_id_cache_.erase(id_it); | |
494 db_cache_.erase(it++); | |
495 } else { | |
496 ++it; | |
497 } | |
498 } | |
499 | |
500 content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE, | |
501 base::Bind(&AutocompleteActionPredictorTable::DeleteRows, table_, | |
502 id_list)); | |
503 UMA_HISTOGRAM_ENUMERATION("AutocompleteActionPredictor.DatabaseAction", | |
504 DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT); | |
505 } | |
506 | |
507 AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch() { | 507 AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch() { |
508 } | 508 } |
509 | 509 |
510 AutocompleteActionPredictor::TransitionalMatch::~TransitionalMatch() { | 510 AutocompleteActionPredictor::TransitionalMatch::~TransitionalMatch() { |
511 } | 511 } |
512 | 512 |
513 } // namespace predictors | 513 } // namespace predictors |
OLD | NEW |