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

Side by Side 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: Addressing Dominic's comments. 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/predictors/predictor_database.h"
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/stringprintf.h"
12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/guid.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "sql/statement.h"
17
18 namespace {
19
20 // TODO(shishir): Rename the table for consistency.
21 const char kAutocompletePredictorTableName[] = "network_action_predictor";
22 const FilePath::CharType kPredictorDatabaseName[] =
23 FILE_PATH_LITERAL("Network Action Predictor");
24
25 // The maximum length allowed for strings in the database.
26 const size_t kMaxDataLength = 2048;
27
28 void LogDatabaseStats(const FilePath& db_path, sql::Connection* db) {
29 int64 db_size;
30 bool success = file_util::GetFileSize(db_path, &db_size);
31 DCHECK(success) << "Failed to get file size for " << db_path.value();
32 UMA_HISTOGRAM_MEMORY_KB("Predictor.DatabaseSizeKB",
33 static_cast<int>(db_size / 1024));
34
35 sql::Statement count_statement(db->GetUniqueStatement(
36 base::StringPrintf("SELECT count(id) FROM %s",
37 kAutocompletePredictorTableName).c_str()));
38 if (!count_statement.Step())
39 return;
40 UMA_HISTOGRAM_COUNTS("AutocompleteActionPredictor.DatabaseRowCount",
41 count_statement.ColumnInt(0));
42 }
43
44 } // namespace
45
46 namespace predictors {
47
48 PredictorTableBase::PredictorTableBase() : db_(NULL) {
49 }
50
51 PredictorTableBase::~PredictorTableBase() {
52 }
53
54 void PredictorTableBase::Initialize(sql::Connection* db) {
55 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
56
57 db_ = db;
58 CreateTableIfNonExistent();
59 }
60
61
62 AutocompleteActionPredictorTable::Row::Row()
63 : number_of_hits(0),
64 number_of_misses(0) {
65 }
66
67 AutocompleteActionPredictorTable::Row::Row(const Row::Id& id,
68 const string16& user_text,
69 const GURL& url,
70 int number_of_hits,
71 int number_of_misses)
72 : id(id),
73 user_text(user_text),
74 url(url),
75 number_of_hits(number_of_hits),
76 number_of_misses(number_of_misses) {
77 }
78
79 AutocompleteActionPredictorTable::Row::Row(const Row& row)
80 : id(row.id),
81 user_text(row.user_text),
82 url(row.url),
83 number_of_hits(row.number_of_hits),
84 number_of_misses(row.number_of_misses) {
85 }
86
87 void AutocompleteActionPredictorTable::GetRow(const Row::Id& id, Row* row) {
88 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
89 if (cancelled_.IsSet() || !db_)
90 return;
91
92 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
93 base::StringPrintf("SELECT * FROM %s WHERE id=?",
94 kAutocompletePredictorTableName).c_str()));
95 statement.BindString(0, id);
96
97 bool success = StepAndInitializeRow(&statement, row);
98 DCHECK(success) << "Failed to get row " << id << " from "
99 << kAutocompletePredictorTableName;
100 }
101
102 void AutocompleteActionPredictorTable::GetAllRows(Rows* row_buffer) {
103 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
104 if (cancelled_.IsSet() || !db_)
105 return;
106
107 CHECK(row_buffer);
108 row_buffer->clear();
109
110 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
111 base::StringPrintf(
112 "SELECT * FROM %s", kAutocompletePredictorTableName).c_str()));
113
114 Row row;
115 while (StepAndInitializeRow(&statement, &row))
116 row_buffer->push_back(row);
117 }
118
119 void AutocompleteActionPredictorTable::AddRow(
120 const AutocompleteActionPredictorTable::Row& row) {
121 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
122 if (cancelled_.IsSet() || !db_)
123 return;
124
125 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
126 base::StringPrintf(
127 "INSERT INTO %s "
128 "(id, user_text, url, number_of_hits, number_of_misses) "
129 "VALUES (?,?,?,?,?)", kAutocompletePredictorTableName).c_str()));
130 BindRowToStatement(row, &statement);
131
132 bool success = statement.Run();
133 DCHECK(success) << "Failed to insert row " << row.id << " into "
134 << kAutocompletePredictorTableName;
135 }
136
137 void AutocompleteActionPredictorTable::UpdateRow(
138 const AutocompleteActionPredictorTable::Row& row) {
139 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
140 if (cancelled_.IsSet() || !db_)
141 return;
142
143 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
144 base::StringPrintf(
145 "UPDATE %s "
146 "SET id=?, user_text=?, url=?, number_of_hits=?, number_of_misses=? "
147 "WHERE id=?1", kAutocompletePredictorTableName).c_str()));
148 BindRowToStatement(row, &statement);
149
150 statement.Run();
151 DCHECK_GT(db_->GetLastChangeCount(), 0);
152 }
153
154 void AutocompleteActionPredictorTable::AddAndUpdateRows(
155 const Rows& rows_to_add,
156 const Rows& rows_to_update) {
157 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
158 if (cancelled_.IsSet() || !db_)
159 return;
160
161 db_->BeginTransaction();
162 for (Rows::const_iterator it = rows_to_add.begin();
163 it != rows_to_add.end(); ++it) {
164 AddRow(*it);
165 }
166 for (Rows::const_iterator it = rows_to_update.begin();
167 it != rows_to_update.end(); ++it) {
168 AddRow(*it);
169 }
170 db_->CommitTransaction();
171 }
172
173 void AutocompleteActionPredictorTable::DeleteRow(const Row::Id& id) {
174 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
175 if (cancelled_.IsSet() || !db_)
176 return;
177
178 DeleteRows(std::vector<Row::Id>(1, id));
179 }
180
181 void AutocompleteActionPredictorTable::DeleteRows(
182 const std::vector<Row::Id>& id_list) {
183 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
184 if (cancelled_.IsSet() || !db_)
185 return;
186
187 sql::Statement statement(db_->GetUniqueStatement(base::StringPrintf(
188 "DELETE FROM %s WHERE id=?",
189 kAutocompletePredictorTableName).c_str()));
190
191 db_->BeginTransaction();
192 for (std::vector<Row::Id>::const_iterator it = id_list.begin();
193 it != id_list.end(); ++it) {
194 statement.BindString(0, *it);
195 statement.Run();
196 statement.Reset();
197 }
198 db_->CommitTransaction();
199 }
200
201 void AutocompleteActionPredictorTable::DeleteAllRows() {
202 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
203 if (cancelled_.IsSet() || !db_)
204 return;
205
206 sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE,
207 base::StringPrintf("DELETE FROM %s",
208 kAutocompletePredictorTableName).c_str()));
209
210 statement.Run();
211 }
212
213 AutocompleteActionPredictorTable::AutocompleteActionPredictorTable()
214 : PredictorTableBase() {
215 }
216
217 AutocompleteActionPredictorTable::~AutocompleteActionPredictorTable() {
218 }
219
220 void AutocompleteActionPredictorTable::CreateTableIfNonExistent() {
221 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
222 if (cancelled_.IsSet() || !db_)
223 return;
224
225 if (db_->DoesTableExist(kAutocompletePredictorTableName))
226 return;
227
228 bool success = db_->Execute(base::StringPrintf(
229 "CREATE TABLE %s ( "
230 "id TEXT PRIMARY KEY, "
231 "user_text TEXT, "
232 "url TEXT, "
233 "number_of_hits INTEGER, "
234 "number_of_misses INTEGER)", kAutocompletePredictorTableName).c_str());
235 DCHECK(success) << "Failed to create " << kAutocompletePredictorTableName
236 << " table.";
237 }
238
239 void AutocompleteActionPredictorTable::BindRowToStatement(
240 const Row& row,
241 sql::Statement* statement) {
242 DCHECK(guid::IsValidGUID(row.id));
243 statement->BindString(0, row.id);
244 statement->BindString16(1, row.user_text.substr(0, kMaxDataLength));
245 statement->BindString(2, row.url.spec().substr(0, kMaxDataLength));
246 statement->BindInt(3, row.number_of_hits);
247 statement->BindInt(4, row.number_of_misses);
248 }
249
250 bool AutocompleteActionPredictorTable::StepAndInitializeRow(
251 sql::Statement* statement,
252 Row* row) {
253 if (!statement->Step())
254 return false;
255
256 row->id = statement->ColumnString(0);
257 row->user_text = statement->ColumnString16(1);
258 row->url = GURL(statement->ColumnString(2));
259 row->number_of_hits = statement->ColumnInt(3);
260 row->number_of_misses = statement->ColumnInt(4);
261 return true;
262 }
263
264
265 PredictorDatabase::PredictorDatabase(Profile* profile)
266 : db_path_(profile->GetPath().Append(kPredictorDatabaseName)),
267 autocomplete_table_(new AutocompleteActionPredictorTable()) {
dominich 2012/03/13 14:55:21 could the tables be created on the DB thread in th
Shishir 2012/03/14 21:14:37 I need to be able to bind to them in the UI thread
268 }
269
270 PredictorDatabase::~PredictorDatabase() {
271 }
272
273 void PredictorDatabase::Initialize() {
274 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::DB));
275
276 db_.set_exclusive_locking();
dominich 2012/03/13 14:55:21 Does this add a mutex that blocks concurrent acces
Shishir 2012/03/14 21:14:37 Does it matter? Isnt all access to the db_ on the
277 bool success = db_.Open(db_path_);
278
279 if (!success) {
280 LOG(ERROR) << "Could not open predictor database @ "
281 << db_path_.AsUTF8Unsafe();
282 return;
283 }
284
285 autocomplete_table_->Initialize(&db_);
286
287 LogDatabaseStats(db_path_, &db_);
288 }
289
290 void PredictorDatabase::ShutdownOnUIThread() {
291 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
292
293 autocomplete_table_->cancelled_.Set();
294 }
295
296 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698