Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3208)

Unified Diff: chrome/browser/predictors/predictor_database.cc

Issue 9610006: Refactoring, moving and renaming the NetworkActionPredictor. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/predictors/predictor_database.cc
diff --git a/chrome/browser/predictors/predictor_database.cc b/chrome/browser/predictors/predictor_database.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3de6fa09666a968385e18539f28291db09031d2a
--- /dev/null
+++ b/chrome/browser/predictors/predictor_database.cc
@@ -0,0 +1,300 @@
+// 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/predictors/predictor_database.h"
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/guid.h"
+#include "content/public/browser/browser_thread.h"
+#include "sql/statement.h"
+
+namespace {
+
+const char kAutocompletePredictorTableName[] = "network_action_predictor";
+const FilePath::CharType kPredictorDatabaseName[] =
+ FILE_PATH_LITERAL("Network Action Predictor");
dominich 2012/03/06 16:42:13 Consider renaming this. Two options: Delete the ol
Shishir 2012/03/14 21:14:37 Adding a todo for this. Once more ppl are ok with
+
+// The maximum length allowed for strings in the database.
+const size_t kMaxDataLength = 2048;
+
+void LogDatabaseStats(const FilePath& db_path, sql::Connection* db) {
+ int64 db_size;
+ bool success = file_util::GetFileSize(db_path, &db_size);
+ DCHECK(success) << "Failed to get file size for " << db_path.value();
+ UMA_HISTOGRAM_MEMORY_KB("Predictor.DatabaseSizeKB",
dominich 2012/03/06 16:42:13 histogram name should be AutocompleteActionPredict
Shishir 2012/03/14 21:14:37 This is the histogram for the overall database so
+ static_cast<int>(db_size / 1024));
+
+ sql::Statement count_statement(db->GetUniqueStatement(
+ base::StringPrintf("SELECT count(id) FROM %s",
+ kAutocompletePredictorTableName).c_str()));
+ if (!count_statement.Step())
+ return;
+ UMA_HISTOGRAM_COUNTS("AutocompleteActionPredictor.DatabaseRowCount",
+ count_statement.ColumnInt(0));
+}
+
+} // namespace
+
+namespace predictors {
+
+PredictorTableBase::PredictorTableBase() : db_(NULL) {
+}
+
+PredictorTableBase::~PredictorTableBase() {
+}
+
+void PredictorTableBase::SetCancelled() {
+ cancelled_.Set();
+}
+
+void PredictorTableBase::Initialize(sql::Connection* db) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+
+ db_ = db;
+ CreateTableIfNonExistant();
+}
+
+
+AutocompleteActionPredictorTable::Row::Row()
+ : number_of_hits(0),
+ number_of_misses(0) {
+}
+
+AutocompleteActionPredictorTable::Row::Row(const Row::Id& id,
+ const string16& user_text,
+ const GURL& url,
+ int number_of_hits,
+ int number_of_misses)
+ : id(id),
+ user_text(user_text),
+ url(url),
+ number_of_hits(number_of_hits),
+ number_of_misses(number_of_misses) {
+}
+
+AutocompleteActionPredictorTable::Row::Row(const Row& row)
+ : id(row.id),
+ user_text(row.user_text),
+ url(row.url),
+ number_of_hits(row.number_of_hits),
+ number_of_misses(row.number_of_misses) {
+}
+
+void AutocompleteActionPredictorTable::GetRow(const Row::Id& id, Row* row) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
+ base::StringPrintf("SELECT * FROM %s WHERE id=?",
+ kAutocompletePredictorTableName).c_str()));
+ statement.BindString(0, id);
+
+ bool success = StepAndInitializeRow(&statement, row);
+ DCHECK(success) << "Failed to get row " << id << " from "
+ << kAutocompletePredictorTableName;
+}
+
+void AutocompleteActionPredictorTable::GetAllRows(
+ std::vector<AutocompleteActionPredictorTable::Row>* row_buffer) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ CHECK(row_buffer);
+ row_buffer->clear();
+
+ sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
+ base::StringPrintf(
+ "SELECT * FROM %s", kAutocompletePredictorTableName).c_str()));
+
+ Row row;
+ while (StepAndInitializeRow(&statement, &row))
+ row_buffer->push_back(row);
+}
+
+void AutocompleteActionPredictorTable::AddRow(
+ const AutocompleteActionPredictorTable::Row& row) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
+ base::StringPrintf(
+ "INSERT INTO %s "
+ "(id, user_text, url, number_of_hits, number_of_misses) "
+ "VALUES (?,?,?,?,?)", kAutocompletePredictorTableName).c_str()));
+ BindRowToStatement(row, &statement);
+
+ bool success = statement.Run();
+ DCHECK(success) << "Failed to insert row " << row.id << " into "
+ << kAutocompletePredictorTableName;
+}
+
+void AutocompleteActionPredictorTable::UpdateRow(
+ const AutocompleteActionPredictorTable::Row& row) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
+ base::StringPrintf(
+ "UPDATE %s "
+ "SET id=?, user_text=?, url=?, number_of_hits=?, number_of_misses=? "
+ "WHERE id=?1", kAutocompletePredictorTableName).c_str()));
+ BindRowToStatement(row, &statement);
+
+ statement.Run();
+ DCHECK_GT(db_->GetLastChangeCount(), 0);
+}
+
+void AutocompleteActionPredictorTable::AddAndUpdateRows(
+ const std::vector<Row>& rows_to_add,
dominich 2012/03/06 16:42:13 consider a typedef for std::vector<Row>
Shishir 2012/03/14 21:14:37 Done.
+ const std::vector<Row>& rows_to_update) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ db_->BeginTransaction();
+ for (std::vector<Row>::const_iterator it = rows_to_add.begin();
+ it != rows_to_add.end(); ++it) {
+ AddRow(*it);
+ }
+ for (std::vector<Row>::const_iterator it = rows_to_update.begin();
+ it != rows_to_update.end(); ++it) {
+ AddRow(*it);
+ }
+ db_->CommitTransaction();
+}
+
+void AutocompleteActionPredictorTable::DeleteRow(const Row::Id& id) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ DeleteRows(std::vector<Row::Id>(1, id));
+}
+
+void AutocompleteActionPredictorTable::DeleteRows(
+ const std::vector<Row::Id>& id_list) {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ sql::Statement statement(db_->GetUniqueStatement(base::StringPrintf(
+ "DELETE FROM %s WHERE id=?",
+ kAutocompletePredictorTableName).c_str()));
+
+ db_->BeginTransaction();
+ for (std::vector<Row::Id>::const_iterator it = id_list.begin();
+ it != id_list.end(); ++it) {
+ statement.BindString(0, *it);
+ statement.Run();
+ statement.Reset();
+ }
+ db_->CommitTransaction();
+}
+
+void AutocompleteActionPredictorTable::DeleteAllRows() {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
+ base::StringPrintf("DELETE FROM %s",
+ kAutocompletePredictorTableName).c_str()));
+
+ statement.Run();
+}
+
+AutocompleteActionPredictorTable::AutocompleteActionPredictorTable()
+ : PredictorTableBase() {
+}
+
+AutocompleteActionPredictorTable::~AutocompleteActionPredictorTable() {
+}
+
+void AutocompleteActionPredictorTable::CreateTableIfNonExistant() {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+ if (cancelled_.IsSet() || !db_)
+ return;
+
+ if (db_->DoesTableExist(kAutocompletePredictorTableName))
+ return;
+
+ bool success = db_->Execute(base::StringPrintf(
+ "CREATE TABLE %s ( "
+ "id TEXT PRIMARY KEY, "
+ "user_text TEXT, "
+ "url TEXT, "
+ "number_of_hits INTEGER, "
+ "number_of_misses INTEGER)", kAutocompletePredictorTableName).c_str());
+ DCHECK(success) << "Failed to create " << kAutocompletePredictorTableName
+ << " table.";
+}
+
+void AutocompleteActionPredictorTable::BindRowToStatement(
+ const Row& row,
+ sql::Statement* statement) {
+ DCHECK(guid::IsValidGUID(row.id));
+ statement->BindString(0, row.id);
+ statement->BindString16(1, row.user_text.substr(0, kMaxDataLength));
+ statement->BindString(2, row.url.spec().substr(0, kMaxDataLength));
+ statement->BindInt(3, row.number_of_hits);
+ statement->BindInt(4, row.number_of_misses);
+}
+
+bool AutocompleteActionPredictorTable::StepAndInitializeRow(
+ sql::Statement* statement,
+ Row* row) {
+ if (!statement->Step())
+ return false;
+
+ row->id = statement->ColumnString(0);
+ row->user_text = statement->ColumnString16(1);
+ row->url = GURL(statement->ColumnString(2));
+ row->number_of_hits = statement->ColumnInt(3);
+ row->number_of_misses = statement->ColumnInt(4);
+ return true;
+}
+
+
+PredictorDatabase::PredictorDatabase(Profile* profile)
+ : db_path_(profile->GetPath().Append(kPredictorDatabaseName)),
+ autocomplete_table_(new AutocompleteActionPredictorTable()) {
+}
+
+PredictorDatabase::~PredictorDatabase() {
+}
+
+void PredictorDatabase::Initialize() {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
+
+ db_.set_exclusive_locking();
+ bool success = db_.Open(db_path_);
+
+ if (!success) {
+ LOG(ERROR) << "Could not open predictor database @ "
+ << db_path_.AsUTF8Unsafe();
+ return;
+ }
+
+ autocomplete_table_->Initialize(&db_);
+
+ LogDatabaseStats(db_path_, &db_);
+}
+
+void PredictorDatabase::ShutdownOnUIThread() {
+ CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ autocomplete_table_->SetCancelled();
dominich 2012/03/06 16:42:13 why do you need a method for this? cancelled_ is a
Shishir 2012/03/14 21:14:37 Done.
+}
+
+} // namespace predictors

Powered by Google App Engine
This is Rietveld 408576698