| Index: chrome/browser/autocomplete/network_action_predictor.cc
 | 
| diff --git a/chrome/browser/autocomplete/network_action_predictor.cc b/chrome/browser/autocomplete/network_action_predictor.cc
 | 
| deleted file mode 100644
 | 
| index 7afc9f82eb941dbc614baa07436d45ee7751d5a5..0000000000000000000000000000000000000000
 | 
| --- a/chrome/browser/autocomplete/network_action_predictor.cc
 | 
| +++ /dev/null
 | 
| @@ -1,512 +0,0 @@
 | 
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | 
| -// Use of this source code is governed by a BSD-style license that can be
 | 
| -// found in the LICENSE file.
 | 
| -
 | 
| -#include "chrome/browser/autocomplete/network_action_predictor.h"
 | 
| -
 | 
| -#include <math.h>
 | 
| -
 | 
| -#include <vector>
 | 
| -
 | 
| -#include "base/bind.h"
 | 
| -#include "base/i18n/case_conversion.h"
 | 
| -#include "base/metrics/histogram.h"
 | 
| -#include "base/string_util.h"
 | 
| -#include "base/stringprintf.h"
 | 
| -#include "base/utf_string_conversions.h"
 | 
| -#include "chrome/browser/autocomplete/autocomplete.h"
 | 
| -#include "chrome/browser/autocomplete/autocomplete_match.h"
 | 
| -#include "chrome/browser/autocomplete/network_action_predictor_database.h"
 | 
| -#include "chrome/browser/history/history.h"
 | 
| -#include "chrome/browser/history/history_notifications.h"
 | 
| -#include "chrome/browser/history/in_memory_database.h"
 | 
| -#include "chrome/browser/prerender/prerender_field_trial.h"
 | 
| -#include "chrome/browser/prerender/prerender_manager.h"
 | 
| -#include "chrome/browser/prerender/prerender_manager_factory.h"
 | 
| -#include "chrome/browser/profiles/profile.h"
 | 
| -#include "chrome/common/chrome_notification_types.h"
 | 
| -#include "chrome/common/guid.h"
 | 
| -#include "content/public/browser/browser_thread.h"
 | 
| -#include "content/public/browser/notification_details.h"
 | 
| -#include "content/public/browser/notification_service.h"
 | 
| -#include "content/public/browser/notification_source.h"
 | 
| -
 | 
| -namespace {
 | 
| -
 | 
| -const float kConfidenceCutoff[] = {
 | 
| -  0.8f,
 | 
| -  0.5f
 | 
| -};
 | 
| -
 | 
| -const size_t kMinimumUserTextLength = 1;
 | 
| -const int kMinimumNumberOfHits = 3;
 | 
| -
 | 
| -COMPILE_ASSERT(arraysize(kConfidenceCutoff) ==
 | 
| -               NetworkActionPredictor::LAST_PREDICT_ACTION,
 | 
| -               ConfidenceCutoff_count_mismatch);
 | 
| -
 | 
| -enum DatabaseAction {
 | 
| -  DATABASE_ACTION_ADD,
 | 
| -  DATABASE_ACTION_UPDATE,
 | 
| -  DATABASE_ACTION_DELETE_SOME,
 | 
| -  DATABASE_ACTION_DELETE_ALL,
 | 
| -  DATABASE_ACTION_COUNT
 | 
| -};
 | 
| -
 | 
| -bool IsAutocompleteMatchSearchType(const AutocompleteMatch& match) {
 | 
| -  switch (match.type) {
 | 
| -    // Matches using the user's default search engine.
 | 
| -    case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED:
 | 
| -    case AutocompleteMatch::SEARCH_HISTORY:
 | 
| -    case AutocompleteMatch::SEARCH_SUGGEST:
 | 
| -    // A match that uses a non-default search engine (e.g. for tab-to-search).
 | 
| -    case AutocompleteMatch::SEARCH_OTHER_ENGINE:
 | 
| -      return true;
 | 
| -
 | 
| -    default:
 | 
| -      return false;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -}
 | 
| -
 | 
| -const int NetworkActionPredictor::kMaximumDaysToKeepEntry = 14;
 | 
| -
 | 
| -double NetworkActionPredictor::hit_weight_ = 1.0;
 | 
| -
 | 
| -NetworkActionPredictor::NetworkActionPredictor(Profile* profile)
 | 
| -    : profile_(profile),
 | 
| -      db_(new NetworkActionPredictorDatabase(profile)),
 | 
| -      initialized_(false) {
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::Initialize, db_));
 | 
| -
 | 
| -  // Request the in-memory database from the history to force it to load so it's
 | 
| -  // available as soon as possible.
 | 
| -  HistoryService* history_service =
 | 
| -      profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
 | 
| -  if (history_service)
 | 
| -    history_service->InMemoryDatabase();
 | 
| -
 | 
| -  // Create local caches using the database as loaded. We will garbage collect
 | 
| -  // rows from the caches and the database once the history service is
 | 
| -  // available.
 | 
| -  std::vector<NetworkActionPredictorDatabase::Row>* rows =
 | 
| -      new std::vector<NetworkActionPredictorDatabase::Row>();
 | 
| -  content::BrowserThread::PostTaskAndReply(
 | 
| -      content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::GetAllRows, db_, rows),
 | 
| -      base::Bind(&NetworkActionPredictor::CreateCaches, AsWeakPtr(),
 | 
| -                 base::Owned(rows)));
 | 
| -
 | 
| -}
 | 
| -
 | 
| -NetworkActionPredictor::~NetworkActionPredictor() {
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::RegisterTransitionalMatches(
 | 
| -    const string16& user_text,
 | 
| -    const AutocompleteResult& result) {
 | 
| -  if (user_text.length() < kMinimumUserTextLength)
 | 
| -    return;
 | 
| -  const string16 lower_user_text(base::i18n::ToLower(user_text));
 | 
| -
 | 
| -  // Merge this in to an existing match if we already saw |user_text|
 | 
| -  std::vector<TransitionalMatch>::iterator match_it =
 | 
| -      std::find(transitional_matches_.begin(), transitional_matches_.end(),
 | 
| -                lower_user_text);
 | 
| -
 | 
| -  if (match_it == transitional_matches_.end()) {
 | 
| -    TransitionalMatch transitional_match;
 | 
| -    transitional_match.user_text = lower_user_text;
 | 
| -    match_it = transitional_matches_.insert(transitional_matches_.end(),
 | 
| -                                            transitional_match);
 | 
| -  }
 | 
| -
 | 
| -  for (AutocompleteResult::const_iterator it = result.begin();
 | 
| -       it != result.end(); ++it) {
 | 
| -    if (std::find(match_it->urls.begin(), match_it->urls.end(),
 | 
| -                  it->destination_url) == match_it->urls.end()) {
 | 
| -      match_it->urls.push_back(it->destination_url);
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::ClearTransitionalMatches() {
 | 
| -  transitional_matches_.clear();
 | 
| -}
 | 
| -
 | 
| -// Given a match, return a recommended action.
 | 
| -NetworkActionPredictor::Action NetworkActionPredictor::RecommendAction(
 | 
| -    const string16& user_text,
 | 
| -    const AutocompleteMatch& match) const {
 | 
| -  bool is_in_db = false;
 | 
| -  const double confidence = CalculateConfidence(user_text, match, &is_in_db);
 | 
| -  DCHECK(confidence >= 0.0 && confidence <= 1.0);
 | 
| -
 | 
| -  UMA_HISTOGRAM_BOOLEAN("NetworkActionPredictor.MatchIsInDb", is_in_db);
 | 
| -
 | 
| -  if (is_in_db) {
 | 
| -    // Multiple enties with the same URL are fine as the confidence may be
 | 
| -    // different.
 | 
| -    tracked_urls_.push_back(std::make_pair(match.destination_url, confidence));
 | 
| -    UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.Confidence",
 | 
| -                             confidence * 100);
 | 
| -  }
 | 
| -
 | 
| -  // Map the confidence to an action.
 | 
| -  Action action = ACTION_NONE;
 | 
| -  for (int i = 0; i < LAST_PREDICT_ACTION; ++i) {
 | 
| -    if (confidence >= kConfidenceCutoff[i]) {
 | 
| -      action = static_cast<Action>(i);
 | 
| -      break;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  // Downgrade prerender to preconnect if this is a search match or if omnibox
 | 
| -  // prerendering is disabled. There are cases when Instant will not handle a
 | 
| -  // search suggestion and in those cases it would be good to prerender the
 | 
| -  // search results, however search engines have not been set up to correctly
 | 
| -  // handle being prerendered and until they are we should avoid it.
 | 
| -  // http://crbug.com/117495
 | 
| -  if (action == ACTION_PRERENDER &&
 | 
| -      (IsAutocompleteMatchSearchType(match) ||
 | 
| -       !prerender::IsOmniboxEnabled(profile_))) {
 | 
| -    action = ACTION_PRECONNECT;
 | 
| -  }
 | 
| -
 | 
| -  return action;
 | 
| -}
 | 
| -
 | 
| -// Return true if the suggestion type warrants a TCP/IP preconnection.
 | 
| -// i.e., it is now quite likely that the user will select the related domain.
 | 
| -// static
 | 
| -bool NetworkActionPredictor::IsPreconnectable(const AutocompleteMatch& match) {
 | 
| -  return IsAutocompleteMatchSearchType(match);
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::Shutdown() {
 | 
| -  db_->OnPredictorDestroyed();
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::Observe(
 | 
| -    int type,
 | 
| -    const content::NotificationSource& source,
 | 
| -    const content::NotificationDetails& details) {
 | 
| -  switch (type) {
 | 
| -    case chrome::NOTIFICATION_HISTORY_URLS_DELETED: {
 | 
| -      DCHECK(initialized_);
 | 
| -      const content::Details<const history::URLsDeletedDetails>
 | 
| -          urls_deleted_details =
 | 
| -              content::Details<const history::URLsDeletedDetails>(details);
 | 
| -      if (urls_deleted_details->all_history)
 | 
| -        DeleteAllRows();
 | 
| -      else
 | 
| -        DeleteRowsWithURLs(urls_deleted_details->urls);
 | 
| -      break;
 | 
| -    }
 | 
| -
 | 
| -    // This notification does not catch all instances of the user navigating
 | 
| -    // from the Omnibox, but it does catch the cases where the dropdown is open
 | 
| -    // and those are the events we're most interested in.
 | 
| -    case chrome::NOTIFICATION_OMNIBOX_OPENED_URL: {
 | 
| -      DCHECK(initialized_);
 | 
| -
 | 
| -      // TODO(dominich): This doesn't need to be synchronous. Investigate
 | 
| -      // posting it as a task to be run later.
 | 
| -      OnOmniboxOpenedUrl(*content::Details<AutocompleteLog>(details).ptr());
 | 
| -      break;
 | 
| -    }
 | 
| -
 | 
| -    case chrome::NOTIFICATION_HISTORY_LOADED: {
 | 
| -      DCHECK(!initialized_);
 | 
| -      TryDeleteOldEntries(content::Details<HistoryService>(details).ptr());
 | 
| -
 | 
| -      notification_registrar_.Remove(this,
 | 
| -                                     chrome::NOTIFICATION_HISTORY_LOADED,
 | 
| -                                     content::Source<Profile>(profile_));
 | 
| -      break;
 | 
| -    }
 | 
| -
 | 
| -    default:
 | 
| -      NOTREACHED() << "Unexpected notification observed.";
 | 
| -      break;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::OnOmniboxOpenedUrl(const AutocompleteLog& log) {
 | 
| -  if (log.text.length() < kMinimumUserTextLength)
 | 
| -    return;
 | 
| -
 | 
| -  const AutocompleteMatch& match = log.result.match_at(log.selected_index);
 | 
| -
 | 
| -  UMA_HISTOGRAM_BOOLEAN(
 | 
| -      StringPrintf("Prerender.OmniboxNavigationsCouldPrerender_%.1f%s",
 | 
| -                   get_hit_weight(),
 | 
| -                   prerender::PrerenderManager::GetModeString()).c_str(),
 | 
| -      prerender::IsOmniboxEnabled(profile_));
 | 
| -
 | 
| -  const GURL& opened_url = match.destination_url;
 | 
| -
 | 
| -  // If the Omnibox triggered a prerender but the URL doesn't match the one the
 | 
| -  // user is navigating to, cancel the prerender.
 | 
| -  prerender::PrerenderManager* prerender_manager =
 | 
| -      prerender::PrerenderManagerFactory::GetForProfile(profile_);
 | 
| -  // |prerender_manager| can be NULL in incognito mode or if prerendering is
 | 
| -  // otherwise disabled.
 | 
| -  if (prerender_manager && !prerender_manager->IsPrerendering(opened_url))
 | 
| -    prerender_manager->CancelOmniboxPrerenders();
 | 
| -
 | 
| -  const string16 lower_user_text(base::i18n::ToLower(log.text));
 | 
| -
 | 
| -  BeginTransaction();
 | 
| -  // Traverse transitional matches for those that have a user_text that is a
 | 
| -  // prefix of |lower_user_text|.
 | 
| -  for (std::vector<TransitionalMatch>::const_iterator it =
 | 
| -       transitional_matches_.begin(); it != transitional_matches_.end();
 | 
| -       ++it) {
 | 
| -    if (!StartsWith(lower_user_text, it->user_text, true))
 | 
| -      continue;
 | 
| -
 | 
| -    // Add entries to the database for those matches.
 | 
| -    for (std::vector<GURL>::const_iterator url_it = it->urls.begin();
 | 
| -         url_it != it->urls.end(); ++url_it) {
 | 
| -      DCHECK(it->user_text.length() >= kMinimumUserTextLength);
 | 
| -      const DBCacheKey key = { it->user_text, *url_it };
 | 
| -      const bool is_hit = (*url_it == opened_url);
 | 
| -
 | 
| -      NetworkActionPredictorDatabase::Row row;
 | 
| -      row.user_text = key.user_text;
 | 
| -      row.url = key.url;
 | 
| -
 | 
| -      DBCacheMap::iterator it = db_cache_.find(key);
 | 
| -      if (it == db_cache_.end()) {
 | 
| -        row.id = guid::GenerateGUID();
 | 
| -        row.number_of_hits = is_hit ? 1 : 0;
 | 
| -        row.number_of_misses = is_hit ? 0 : 1;
 | 
| -
 | 
| -        AddRow(key, row);
 | 
| -      } else {
 | 
| -        DCHECK(db_id_cache_.find(key) != db_id_cache_.end());
 | 
| -        row.id = db_id_cache_.find(key)->second;
 | 
| -        row.number_of_hits = it->second.number_of_hits + (is_hit ? 1 : 0);
 | 
| -        row.number_of_misses = it->second.number_of_misses + (is_hit ? 0 : 1);
 | 
| -
 | 
| -        UpdateRow(it, row);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -  CommitTransaction();
 | 
| -
 | 
| -  ClearTransitionalMatches();
 | 
| -
 | 
| -  // Check against tracked urls and log accuracy for the confidence we
 | 
| -  // predicted.
 | 
| -  for (std::vector<std::pair<GURL, double> >::const_iterator it =
 | 
| -       tracked_urls_.begin(); it != tracked_urls_.end();
 | 
| -       ++it) {
 | 
| -    if (opened_url == it->first) {
 | 
| -      UMA_HISTOGRAM_COUNTS_100("NetworkActionPredictor.AccurateCount",
 | 
| -                               it->second * 100);
 | 
| -    }
 | 
| -  }
 | 
| -  tracked_urls_.clear();
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::DeleteOldIdsFromCaches(
 | 
| -    history::URLDatabase* url_db,
 | 
| -    std::vector<NetworkActionPredictorDatabase::Row::Id>* id_list) {
 | 
| -  CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 | 
| -  DCHECK(url_db);
 | 
| -  DCHECK(id_list);
 | 
| -  id_list->clear();
 | 
| -  for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) {
 | 
| -    history::URLRow url_row;
 | 
| -
 | 
| -    if ((url_db->GetRowForURL(it->first.url, &url_row) == 0) ||
 | 
| -        ((base::Time::Now() - url_row.last_visit()).InDays() >
 | 
| -         kMaximumDaysToKeepEntry)) {
 | 
| -      const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first);
 | 
| -      DCHECK(id_it != db_id_cache_.end());
 | 
| -      id_list->push_back(id_it->second);
 | 
| -      db_id_cache_.erase(id_it);
 | 
| -      db_cache_.erase(it++);
 | 
| -    } else {
 | 
| -      ++it;
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::DeleteOldEntries(history::URLDatabase* url_db) {
 | 
| -  CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 | 
| -  DCHECK(!initialized_);
 | 
| -
 | 
| -  std::vector<NetworkActionPredictorDatabase::Row::Id> ids_to_delete;
 | 
| -  DeleteOldIdsFromCaches(url_db, &ids_to_delete);
 | 
| -
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::DeleteRows, db_,
 | 
| -                 ids_to_delete));
 | 
| -
 | 
| -  // Register for notifications and set the |initialized_| flag.
 | 
| -  notification_registrar_.Add(this, chrome::NOTIFICATION_OMNIBOX_OPENED_URL,
 | 
| -                              content::Source<Profile>(profile_));
 | 
| -  notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
 | 
| -                              content::Source<Profile>(profile_));
 | 
| -  initialized_ = true;
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::CreateCaches(
 | 
| -    std::vector<NetworkActionPredictorDatabase::Row>* rows) {
 | 
| -  CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 | 
| -  DCHECK(!initialized_);
 | 
| -  DCHECK(db_cache_.empty());
 | 
| -  DCHECK(db_id_cache_.empty());
 | 
| -
 | 
| -  for (std::vector<NetworkActionPredictorDatabase::Row>::const_iterator it =
 | 
| -       rows->begin(); it != rows->end(); ++it) {
 | 
| -    const DBCacheKey key = { it->user_text, it->url };
 | 
| -    const DBCacheValue value = { it->number_of_hits, it->number_of_misses };
 | 
| -    db_cache_[key] = value;
 | 
| -    db_id_cache_[key] = it->id;
 | 
| -  }
 | 
| -
 | 
| -  // If the history service is ready, delete any old or invalid entries.
 | 
| -  HistoryService* history_service =
 | 
| -      profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
 | 
| -  if (!TryDeleteOldEntries(history_service)) {
 | 
| -    // Wait for the notification that the history service is ready and the URL
 | 
| -    // DB is loaded.
 | 
| -    notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED,
 | 
| -                                content::Source<Profile>(profile_));
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -bool NetworkActionPredictor::TryDeleteOldEntries(HistoryService* service) {
 | 
| -  if (!service)
 | 
| -    return false;
 | 
| -
 | 
| -  history::URLDatabase* url_db = service->InMemoryDatabase();
 | 
| -  if (!url_db)
 | 
| -    return false;
 | 
| -
 | 
| -  DeleteOldEntries(url_db);
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -double NetworkActionPredictor::CalculateConfidence(
 | 
| -    const string16& user_text,
 | 
| -    const AutocompleteMatch& match,
 | 
| -    bool* is_in_db) const {
 | 
| -  const DBCacheKey key = { user_text, match.destination_url };
 | 
| -
 | 
| -  *is_in_db = false;
 | 
| -  if (user_text.length() < kMinimumUserTextLength)
 | 
| -    return 0.0;
 | 
| -
 | 
| -  const DBCacheMap::const_iterator iter = db_cache_.find(key);
 | 
| -  if (iter == db_cache_.end())
 | 
| -    return 0.0;
 | 
| -
 | 
| -  *is_in_db = true;
 | 
| -  return CalculateConfidenceForDbEntry(iter);
 | 
| -}
 | 
| -
 | 
| -double NetworkActionPredictor::CalculateConfidenceForDbEntry(
 | 
| -    DBCacheMap::const_iterator iter) const {
 | 
| -  const DBCacheValue& value = iter->second;
 | 
| -  if (value.number_of_hits < kMinimumNumberOfHits)
 | 
| -    return 0.0;
 | 
| -
 | 
| -  const double number_of_hits = value.number_of_hits * hit_weight_;
 | 
| -  return number_of_hits / (number_of_hits + value.number_of_misses);
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::AddRow(
 | 
| -    const DBCacheKey& key,
 | 
| -    const NetworkActionPredictorDatabase::Row& row) {
 | 
| -  if (!initialized_)
 | 
| -    return;
 | 
| -
 | 
| -  DBCacheValue value = { row.number_of_hits, row.number_of_misses };
 | 
| -  db_cache_[key] = value;
 | 
| -  db_id_cache_[key] = row.id;
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::AddRow, db_, row));
 | 
| -
 | 
| -  UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction",
 | 
| -                            DATABASE_ACTION_ADD, DATABASE_ACTION_COUNT);
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::UpdateRow(
 | 
| -    DBCacheMap::iterator it,
 | 
| -    const NetworkActionPredictorDatabase::Row& row) {
 | 
| -  if (!initialized_)
 | 
| -    return;
 | 
| -
 | 
| -  DCHECK(it != db_cache_.end());
 | 
| -  it->second.number_of_hits = row.number_of_hits;
 | 
| -  it->second.number_of_misses = row.number_of_misses;
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::UpdateRow, db_, row));
 | 
| -  UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction",
 | 
| -                            DATABASE_ACTION_UPDATE, DATABASE_ACTION_COUNT);
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::DeleteAllRows() {
 | 
| -  if (!initialized_)
 | 
| -    return;
 | 
| -
 | 
| -  db_cache_.clear();
 | 
| -  db_id_cache_.clear();
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::DeleteAllRows, db_));
 | 
| -  UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction",
 | 
| -                            DATABASE_ACTION_DELETE_ALL, DATABASE_ACTION_COUNT);
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::DeleteRowsWithURLs(const std::set<GURL>& urls) {
 | 
| -  if (!initialized_)
 | 
| -    return;
 | 
| -
 | 
| -  std::vector<NetworkActionPredictorDatabase::Row::Id> id_list;
 | 
| -
 | 
| -  for (DBCacheMap::iterator it = db_cache_.begin(); it != db_cache_.end();) {
 | 
| -    if (urls.find(it->first.url) != urls.end()) {
 | 
| -      const DBIdCacheMap::iterator id_it = db_id_cache_.find(it->first);
 | 
| -      DCHECK(id_it != db_id_cache_.end());
 | 
| -      id_list.push_back(id_it->second);
 | 
| -      db_id_cache_.erase(id_it);
 | 
| -      db_cache_.erase(it++);
 | 
| -    } else {
 | 
| -      ++it;
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::DeleteRows, db_, id_list));
 | 
| -  UMA_HISTOGRAM_ENUMERATION("NetworkActionPredictor.DatabaseAction",
 | 
| -                            DATABASE_ACTION_DELETE_SOME, DATABASE_ACTION_COUNT);
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::BeginTransaction() {
 | 
| -  if (!initialized_)
 | 
| -    return;
 | 
| -
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::BeginTransaction, db_));
 | 
| -}
 | 
| -
 | 
| -void NetworkActionPredictor::CommitTransaction() {
 | 
| -  if (!initialized_)
 | 
| -    return;
 | 
| -
 | 
| -  content::BrowserThread::PostTask(content::BrowserThread::DB, FROM_HERE,
 | 
| -      base::Bind(&NetworkActionPredictorDatabase::CommitTransaction, db_));
 | 
| -}
 | 
| -
 | 
| -NetworkActionPredictor::TransitionalMatch::TransitionalMatch() {
 | 
| -}
 | 
| -
 | 
| -NetworkActionPredictor::TransitionalMatch::~TransitionalMatch() {
 | 
| -}
 | 
| 
 |