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

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor_tables.cc

Issue 2478823002: predictors: ResourcePrefetchPredictorTables cleanup. (Closed)
Patch Set: lint Created 4 years, 1 month 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/resource_prefetch_predictor_tables.h" 5 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
6 6
7 #include <stdint.h>
8
9 #include <algorithm> 7 #include <algorithm>
10 #include <memory>
11 #include <utility> 8 #include <utility>
12 9
13 #include "base/logging.h" 10 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
15 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
16 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
17 #include "content/public/browser/browser_thread.h" 14 #include "content/public/browser/browser_thread.h"
18 #include "sql/meta_table.h"
19 #include "sql/statement.h" 15 #include "sql/statement.h"
20 #include "sql/transaction.h"
21 16
22 using content::BrowserThread; 17 using google::protobuf::MessageLite;
23 using sql::Statement;
Benoit L 2016/11/04 15:03:10 Why?
alexilin 2016/11/04 15:29:47 sql::Statement is more readable than just Statemen
24 18
25 namespace { 19 namespace {
26 20
27 using PrefetchData = predictors::PrefetchData;
28 using RedirectData = predictors::RedirectData;
29 using ::google::protobuf::MessageLite;
30
31 const char kMetadataTableName[] = "resource_prefetch_predictor_metadata"; 21 const char kMetadataTableName[] = "resource_prefetch_predictor_metadata";
32 const char kUrlResourceTableName[] = "resource_prefetch_predictor_url"; 22 const char kUrlResourceTableName[] = "resource_prefetch_predictor_url";
33 const char kUrlRedirectTableName[] = "resource_prefetch_predictor_url_redirect"; 23 const char kUrlRedirectTableName[] = "resource_prefetch_predictor_url_redirect";
34 const char kHostResourceTableName[] = "resource_prefetch_predictor_host"; 24 const char kHostResourceTableName[] = "resource_prefetch_predictor_host";
35 const char kHostRedirectTableName[] = 25 const char kHostRedirectTableName[] =
36 "resource_prefetch_predictor_host_redirect"; 26 "resource_prefetch_predictor_host_redirect";
37 27
38 const char kCreateGlobalMetadataStatementTemplate[] = 28 const char kCreateGlobalMetadataStatementTemplate[] =
39 "CREATE TABLE %s ( " 29 "CREATE TABLE %s ( "
40 "key TEXT, value INTEGER, " 30 "key TEXT, value INTEGER, "
41 "PRIMARY KEY (key))"; 31 "PRIMARY KEY (key))";
42 const char kCreateProtoTableStatementTemplate[] = 32 const char kCreateProtoTableStatementTemplate[] =
43 "CREATE TABLE %s ( " 33 "CREATE TABLE %s ( "
44 "key TEXT, " 34 "key TEXT, "
45 "proto BLOB, " 35 "proto BLOB, "
46 "PRIMARY KEY(key))"; 36 "PRIMARY KEY(key))";
47 const char kInsertProtoTableStatementTemplate[] = 37 const char kInsertProtoTableStatementTemplate[] =
48 "INSERT INTO %s (key, proto) VALUES (?,?)"; 38 "INSERT INTO %s (key, proto) VALUES (?,?)";
49 const char kDeleteProtoTableStatementTemplate[] = "DELETE FROM %s WHERE key=?"; 39 const char kDeleteProtoTableStatementTemplate[] = "DELETE FROM %s WHERE key=?";
50 40
51 void BindProtoDataToStatement(const std::string& key, 41 void BindProtoDataToStatement(const std::string& key,
52 const MessageLite& data, 42 const MessageLite& data,
53 Statement* statement) { 43 sql::Statement* statement) {
54 int size = data.ByteSize(); 44 int size = data.ByteSize();
55 DCHECK_GT(size, 0); 45 DCHECK_GT(size, 0);
56 std::vector<char> proto_buffer(size); 46 std::vector<char> proto_buffer(size);
57 data.SerializeToArray(&proto_buffer[0], size); 47 data.SerializeToArray(&proto_buffer[0], size);
58 48
59 statement->BindString(0, key); 49 statement->BindString(0, key);
60 statement->BindBlob(1, &proto_buffer[0], size); 50 statement->BindBlob(1, &proto_buffer[0], size);
61 } 51 }
62 52
63 bool StepAndInitializeProtoData(Statement* statement, 53 bool StepAndInitializeProtoData(sql::Statement* statement,
64 std::string* key, 54 std::string* key,
65 MessageLite* data) { 55 MessageLite* data) {
66 if (!statement->Step()) 56 if (!statement->Step())
67 return false; 57 return false;
68 58
69 *key = statement->ColumnString(0); 59 *key = statement->ColumnString(0);
70 60
71 int size = statement->ColumnByteLength(1); 61 int size = statement->ColumnByteLength(1);
72 const void* blob = statement->ColumnBlob(1); 62 const void* blob = statement->ColumnBlob(1);
73 DCHECK(blob); 63 DCHECK(blob);
74 data->ParseFromArray(blob, size); 64 data->ParseFromArray(blob, size);
75 65
76 return true; 66 return true;
77 } 67 }
78 68
79 } // namespace 69 } // namespace
80 70
81 namespace predictors { 71 namespace predictors {
82 72
83 // static 73 using content::BrowserThread;
84 void ResourcePrefetchPredictorTables::TrimResources(
85 PrefetchData* data,
86 size_t max_consecutive_misses) {
87 auto new_end = std::remove_if(
88 data->mutable_resources()->begin(), data->mutable_resources()->end(),
89 [max_consecutive_misses](const ResourceData& x) {
90 return x.consecutive_misses() >= max_consecutive_misses;
91 });
92 data->mutable_resources()->erase(new_end, data->mutable_resources()->end());
93 }
94
95 // static
96 void ResourcePrefetchPredictorTables::SortResources(PrefetchData* data) {
97 std::sort(data->mutable_resources()->begin(),
98 data->mutable_resources()->end(),
99 [](const ResourceData& x, const ResourceData& y) {
100 // Decreasing score ordering.
101 return ComputeResourceScore(x) > ComputeResourceScore(y);
102 });
103 }
104
105 // static
106 void ResourcePrefetchPredictorTables::TrimRedirects(
107 RedirectData* data,
108 size_t max_consecutive_misses) {
109 auto new_end =
110 std::remove_if(data->mutable_redirect_endpoints()->begin(),
111 data->mutable_redirect_endpoints()->end(),
112 [max_consecutive_misses](const RedirectStat& x) {
113 return x.consecutive_misses() >= max_consecutive_misses;
114 });
115 data->mutable_redirect_endpoints()->erase(
116 new_end, data->mutable_redirect_endpoints()->end());
117 }
118 74
119 void ResourcePrefetchPredictorTables::GetAllData( 75 void ResourcePrefetchPredictorTables::GetAllData(
120 PrefetchDataMap* url_data_map, 76 PrefetchDataMap* url_data_map,
121 PrefetchDataMap* host_data_map, 77 PrefetchDataMap* host_data_map,
122 RedirectDataMap* url_redirect_data_map, 78 RedirectDataMap* url_redirect_data_map,
123 RedirectDataMap* host_redirect_data_map) { 79 RedirectDataMap* host_redirect_data_map) {
124 TRACE_EVENT0("browser", "ResourcePrefetchPredictor::GetAllData"); 80 TRACE_EVENT0("browser", "ResourcePrefetchPredictor::GetAllData");
125 DCHECK_CURRENTLY_ON(BrowserThread::DB); 81 DCHECK_CURRENTLY_ON(BrowserThread::DB);
126 if (CantAccessDatabase()) 82 if (CantAccessDatabase())
127 return; 83 return;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 return; 180 return;
225 181
226 DeleteDataHelper(key_type, PrefetchDataType::REDIRECT, {key}); 182 DeleteDataHelper(key_type, PrefetchDataType::REDIRECT, {key});
227 } 183 }
228 184
229 void ResourcePrefetchPredictorTables::DeleteAllData() { 185 void ResourcePrefetchPredictorTables::DeleteAllData() {
230 DCHECK_CURRENTLY_ON(BrowserThread::DB); 186 DCHECK_CURRENTLY_ON(BrowserThread::DB);
231 if (CantAccessDatabase()) 187 if (CantAccessDatabase())
232 return; 188 return;
233 189
234 Statement deleter; 190 sql::Statement deleter;
235 for (const char* table_name : 191 for (const char* table_name :
236 {kUrlResourceTableName, kUrlRedirectTableName, kHostResourceTableName, 192 {kUrlResourceTableName, kUrlRedirectTableName, kHostResourceTableName,
237 kHostRedirectTableName}) { 193 kHostRedirectTableName}) {
238 deleter.Assign(DB()->GetUniqueStatement( 194 deleter.Assign(DB()->GetUniqueStatement(
239 base::StringPrintf("DELETE FROM %s", table_name).c_str())); 195 base::StringPrintf("DELETE FROM %s", table_name).c_str()));
240 deleter.Run(); 196 deleter.Run();
241 } 197 }
242 } 198 }
243 199
244 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() 200 // static
245 : PredictorTableBase() {} 201 void ResourcePrefetchPredictorTables::TrimResources(
202 PrefetchData* data,
203 size_t max_consecutive_misses) {
204 auto new_end = std::remove_if(
205 data->mutable_resources()->begin(), data->mutable_resources()->end(),
206 [max_consecutive_misses](const ResourceData& x) {
207 return x.consecutive_misses() >= max_consecutive_misses;
208 });
209 data->mutable_resources()->erase(new_end, data->mutable_resources()->end());
210 }
211
212 // static
213 void ResourcePrefetchPredictorTables::SortResources(PrefetchData* data) {
214 std::sort(data->mutable_resources()->begin(),
215 data->mutable_resources()->end(),
216 [](const ResourceData& x, const ResourceData& y) {
217 // Decreasing score ordering.
218 return ComputeResourceScore(x) > ComputeResourceScore(y);
219 });
220 }
221
222 // static
223 float ResourcePrefetchPredictorTables::ComputeResourceScore(
224 const ResourceData& data) {
225 // The ranking is done by considering, in this order:
226 // 1. Resource Priority
227 // 2. Request resource type
228 // 3. Finally, the average position, giving a higher priotity to earlier
229 // resources.
230
231 int priority_multiplier;
232 switch (data.priority()) {
233 case ResourceData::REQUEST_PRIORITY_HIGHEST:
234 priority_multiplier = 3;
235 break;
236 case ResourceData::REQUEST_PRIORITY_MEDIUM:
237 priority_multiplier = 2;
238 break;
239 case ResourceData::REQUEST_PRIORITY_LOW:
240 case ResourceData::REQUEST_PRIORITY_LOWEST:
241 case ResourceData::REQUEST_PRIORITY_IDLE:
242 default:
243 priority_multiplier = 1;
244 break;
245 }
246
247 int type_multiplier;
248 switch (data.resource_type()) {
249 case ResourceData::RESOURCE_TYPE_STYLESHEET:
250 case ResourceData::RESOURCE_TYPE_SCRIPT:
251 type_multiplier = 3;
252 break;
253 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE:
254 type_multiplier = 2;
255 break;
256 case ResourceData::RESOURCE_TYPE_IMAGE:
257 default:
258 type_multiplier = 1;
259 }
260
261 constexpr int kMaxResourcesPerType = 100;
262 return kMaxResourcesPerType *
263 (priority_multiplier * 100 + type_multiplier * 10) -
264 data.average_position();
265 }
266
267 // static
268 void ResourcePrefetchPredictorTables::TrimRedirects(
269 RedirectData* data,
270 size_t max_consecutive_misses) {
271 auto new_end =
272 std::remove_if(data->mutable_redirect_endpoints()->begin(),
273 data->mutable_redirect_endpoints()->end(),
274 [max_consecutive_misses](const RedirectStat& x) {
275 return x.consecutive_misses() >= max_consecutive_misses;
276 });
277 data->mutable_redirect_endpoints()->erase(
278 new_end, data->mutable_redirect_endpoints()->end());
279 }
280
281 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() {}
246 282
247 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {} 283 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {}
248 284
249 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper( 285 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper(
250 PrefetchKeyType key_type, 286 PrefetchKeyType key_type,
251 PrefetchDataMap* data_map) { 287 PrefetchDataMap* data_map) {
252 // Read the resources table and organize it per primary key. 288 // Read the resources table and organize it per primary key.
253 const char* table_name = GetTableName(key_type, PrefetchDataType::RESOURCE); 289 const char* table_name = GetTableName(key_type, PrefetchDataType::RESOURCE);
254 Statement resource_reader(DB()->GetUniqueStatement( 290 sql::Statement resource_reader(DB()->GetUniqueStatement(
255 base::StringPrintf("SELECT * FROM %s", table_name).c_str())); 291 base::StringPrintf("SELECT * FROM %s", table_name).c_str()));
256 292
257 PrefetchData data; 293 PrefetchData data;
258 std::string key; 294 std::string key;
259 while (StepAndInitializeProtoData(&resource_reader, &key, &data)) { 295 while (StepAndInitializeProtoData(&resource_reader, &key, &data)) {
260 data_map->insert(std::make_pair(key, data)); 296 data_map->insert(std::make_pair(key, data));
261 DCHECK_EQ(data.primary_key(), key); 297 DCHECK_EQ(data.primary_key(), key);
262 } 298 }
263 299
264 // Sort each of the resource vectors by score. 300 // Sort each of the resource vectors by score.
265 for (auto& kv : *data_map) { 301 for (auto& kv : *data_map) {
266 SortResources(&(kv.second)); 302 SortResources(&(kv.second));
267 } 303 }
268 } 304 }
269 305
270 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper( 306 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper(
271 PrefetchKeyType key_type, 307 PrefetchKeyType key_type,
272 RedirectDataMap* data_map) { 308 RedirectDataMap* data_map) {
273 // Read the redirects table and organize it per primary key. 309 // Read the redirects table and organize it per primary key.
274 const char* table_name = GetTableName(key_type, PrefetchDataType::REDIRECT); 310 const char* table_name = GetTableName(key_type, PrefetchDataType::REDIRECT);
275 Statement redirect_reader(DB()->GetUniqueStatement( 311 sql::Statement redirect_reader(DB()->GetUniqueStatement(
276 base::StringPrintf("SELECT * FROM %s", table_name).c_str())); 312 base::StringPrintf("SELECT * FROM %s", table_name).c_str()));
277 313
278 RedirectData data; 314 RedirectData data;
279 std::string key; 315 std::string key;
280 while (StepAndInitializeProtoData(&redirect_reader, &key, &data)) { 316 while (StepAndInitializeProtoData(&redirect_reader, &key, &data)) {
281 data_map->insert(std::make_pair(key, data)); 317 data_map->insert(std::make_pair(key, data));
282 DCHECK_EQ(data.primary_key(), key); 318 DCHECK_EQ(data.primary_key(), key);
283 } 319 }
284 } 320 }
285 321
286 bool ResourcePrefetchPredictorTables::UpdateDataHelper( 322 bool ResourcePrefetchPredictorTables::UpdateDataHelper(
287 PrefetchKeyType key_type, 323 PrefetchKeyType key_type,
288 PrefetchDataType data_type, 324 PrefetchDataType data_type,
289 const std::string& key, 325 const std::string& key,
290 const MessageLite& data) { 326 const MessageLite& data) {
291 // Delete the older data from the table. 327 // Delete the older data from the table.
292 std::unique_ptr<Statement> deleter( 328 std::unique_ptr<sql::Statement> deleter(
293 GetTableUpdateStatement(key_type, data_type, TableOperationType::REMOVE)); 329 GetTableUpdateStatement(key_type, data_type, TableOperationType::REMOVE));
294 deleter->BindString(0, key); 330 deleter->BindString(0, key);
295 if (!deleter->Run()) 331 if (!deleter->Run())
296 return false; 332 return false;
297 333
298 // Add the new data to the table. 334 // Add the new data to the table.
299 std::unique_ptr<Statement> inserter( 335 std::unique_ptr<sql::Statement> inserter(
300 GetTableUpdateStatement(key_type, data_type, TableOperationType::INSERT)); 336 GetTableUpdateStatement(key_type, data_type, TableOperationType::INSERT));
301 BindProtoDataToStatement(key, data, inserter.get()); 337 BindProtoDataToStatement(key, data, inserter.get());
302 return inserter->Run(); 338 return inserter->Run();
303 } 339 }
304 340
305 void ResourcePrefetchPredictorTables::DeleteDataHelper( 341 void ResourcePrefetchPredictorTables::DeleteDataHelper(
306 PrefetchKeyType key_type, 342 PrefetchKeyType key_type,
307 PrefetchDataType data_type, 343 PrefetchDataType data_type,
308 const std::vector<std::string>& keys) { 344 const std::vector<std::string>& keys) {
309 for (const std::string& key : keys) { 345 for (const std::string& key : keys) {
310 std::unique_ptr<Statement> deleter(GetTableUpdateStatement( 346 std::unique_ptr<sql::Statement> deleter(GetTableUpdateStatement(
311 key_type, data_type, TableOperationType::REMOVE)); 347 key_type, data_type, TableOperationType::REMOVE));
312 deleter->BindString(0, key); 348 deleter->BindString(0, key);
313 deleter->Run(); 349 deleter->Run();
314 } 350 }
315 } 351 }
316 352
317 // static 353 void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() {
318 float ResourcePrefetchPredictorTables::ComputeResourceScore( 354 DCHECK_CURRENTLY_ON(BrowserThread::DB);
319 const ResourceData& data) { 355 if (CantAccessDatabase())
320 // The ranking is done by considering, in this order: 356 return;
321 // 1. Resource Priority
322 // 2. Request resource type
323 // 3. Finally, the average position, giving a higher priotity to earlier
324 // resources.
325 357
326 int priority_multiplier; 358 // Database initialization is all-or-nothing.
327 switch (data.priority()) { 359 bool success = DB()->BeginTransaction();
328 case ResourceData::REQUEST_PRIORITY_HIGHEST: 360
329 priority_multiplier = 3; 361 success = success && DropTablesIfOutdated();
330 break; 362
331 case ResourceData::REQUEST_PRIORITY_MEDIUM: 363 for (const char* table_name :
332 priority_multiplier = 2; 364 {kUrlResourceTableName, kHostResourceTableName, kUrlRedirectTableName,
333 break; 365 kHostRedirectTableName}) {
334 case ResourceData::REQUEST_PRIORITY_LOW: 366 success = success &&
335 case ResourceData::REQUEST_PRIORITY_LOWEST: 367 (DB()->DoesTableExist(table_name) ||
336 case ResourceData::REQUEST_PRIORITY_IDLE: 368 DB()->Execute(base::StringPrintf(
337 default: 369 kCreateProtoTableStatementTemplate, table_name)
338 priority_multiplier = 1; 370 .c_str()));
339 break;
340 } 371 }
341 372
342 int type_multiplier; 373 if (success)
343 switch (data.resource_type()) { 374 success = DB()->CommitTransaction();
344 case ResourceData::RESOURCE_TYPE_STYLESHEET: 375 else
345 case ResourceData::RESOURCE_TYPE_SCRIPT: 376 DB()->RollbackTransaction();
346 type_multiplier = 3;
347 break;
348 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE:
349 type_multiplier = 2;
350 break;
351 case ResourceData::RESOURCE_TYPE_IMAGE:
352 default:
353 type_multiplier = 1;
354 }
355 377
356 constexpr int kMaxResourcesPerType = 100; 378 if (!success)
357 return kMaxResourcesPerType * 379 ResetDB();
358 (priority_multiplier * 100 + type_multiplier * 10) -
359 data.average_position();
360 } 380 }
361 381
362 // static 382 void ResourcePrefetchPredictorTables::LogDatabaseStats() {
363 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( 383 DCHECK_CURRENTLY_ON(BrowserThread::DB);
364 sql::Connection* db) { 384 if (CantAccessDatabase())
365 int version = GetDatabaseVersion(db); 385 return;
366 bool success = true; 386
387 sql::Statement statement(DB()->GetUniqueStatement(
388 base::StringPrintf("SELECT count(*) FROM %s", kUrlResourceTableName)
389 .c_str()));
390 if (statement.Step())
391 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableRowCount",
392 statement.ColumnInt(0));
393
394 statement.Assign(DB()->GetUniqueStatement(
395 base::StringPrintf("SELECT count(*) FROM %s", kHostResourceTableName)
396 .c_str()));
397 if (statement.Step())
398 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount",
399 statement.ColumnInt(0));
400 }
401
402 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated() {
403 int version = GetDatabaseVersion();
367 // Too new is also a problem. 404 // Too new is also a problem.
368 bool incompatible_version = version != kDatabaseVersion; 405 bool incompatible_version = version != kDatabaseVersion;
369 406
370 // These are deprecated tables but they still have to be removed if present. 407 // These are deprecated tables but they still have to be removed if present.
371 const char kUrlMetadataTableName[] = 408 static const char kUrlMetadataTableName[] =
372 "resource_prefetch_predictor_url_metadata"; 409 "resource_prefetch_predictor_url_metadata";
373 const char kHostMetadataTableName[] = 410 static const char kHostMetadataTableName[] =
374 "resource_prefetch_predictor_host_metadata"; 411 "resource_prefetch_predictor_host_metadata";
375 412
413 bool success = true;
376 if (incompatible_version) { 414 if (incompatible_version) {
377 for (const char* table_name : 415 for (const char* table_name :
378 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName, 416 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName,
379 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName, 417 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName,
380 kHostMetadataTableName}) { 418 kHostMetadataTableName}) {
381 success = 419 success = success &&
382 success && 420 DB()->Execute(
383 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name) 421 base::StringPrintf("DROP TABLE IF EXISTS %s", table_name)
384 .c_str()); 422 .c_str());
385 } 423 }
386 }
387 424
388 if (incompatible_version) {
389 success = 425 success =
390 success && 426 success &&
391 db->Execute(base::StringPrintf(kCreateGlobalMetadataStatementTemplate, 427 DB()->Execute(base::StringPrintf(kCreateGlobalMetadataStatementTemplate,
392 kMetadataTableName) 428 kMetadataTableName)
393 .c_str()); 429 .c_str());
394 success = success && SetDatabaseVersion(db, kDatabaseVersion); 430 success = success && SetDatabaseVersion(kDatabaseVersion);
395 } 431 }
396 432
397 return success; 433 return success;
398 } 434 }
399 435
400 // static 436 int ResourcePrefetchPredictorTables::GetDatabaseVersion() {
401 int ResourcePrefetchPredictorTables::GetDatabaseVersion(sql::Connection* db) {
402 int version = 0; 437 int version = 0;
403 if (db->DoesTableExist(kMetadataTableName)) { 438 if (DB()->DoesTableExist(kMetadataTableName)) {
404 sql::Statement statement(db->GetUniqueStatement( 439 sql::Statement statement(DB()->GetUniqueStatement(
405 base::StringPrintf("SELECT value FROM %s WHERE key='version'", 440 base::StringPrintf("SELECT value FROM %s WHERE key='version'",
406 kMetadataTableName) 441 kMetadataTableName)
407 .c_str())); 442 .c_str()));
408 if (statement.Step()) 443 if (statement.Step())
409 version = statement.ColumnInt(0); 444 version = statement.ColumnInt(0);
410 } 445 }
411 return version; 446 return version;
412 } 447 }
413 448
414 // static 449 bool ResourcePrefetchPredictorTables::SetDatabaseVersion(int version) {
415 bool ResourcePrefetchPredictorTables::SetDatabaseVersion(sql::Connection* db, 450 sql::Statement statement(DB()->GetUniqueStatement(
416 int version) {
417 sql::Statement statement(db->GetUniqueStatement(
418 base::StringPrintf( 451 base::StringPrintf(
419 "INSERT OR REPLACE INTO %s (key,value) VALUES ('version',%d)", 452 "INSERT OR REPLACE INTO %s (key,value) VALUES ('version',%d)",
420 kMetadataTableName, version) 453 kMetadataTableName, version)
421 .c_str())); 454 .c_str()));
422 return statement.Run(); 455 return statement.Run();
423 } 456 }
424 457
425 void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() { 458 std::unique_ptr<sql::Statement>
426 DCHECK_CURRENTLY_ON(BrowserThread::DB);
427 if (CantAccessDatabase())
428 return;
429
430 // Database initialization is all-or-nothing.
431 sql::Connection* db = DB();
432 sql::Transaction transaction{db};
433 bool success = transaction.Begin();
434
435 success = success && DropTablesIfOutdated(db);
436
437 for (const char* table_name :
438 {kUrlResourceTableName, kHostResourceTableName, kUrlRedirectTableName,
439 kHostRedirectTableName}) {
440 success = success &&
441 (db->DoesTableExist(table_name) ||
442 db->Execute(base::StringPrintf(
443 kCreateProtoTableStatementTemplate, table_name)
444 .c_str()));
445 }
446
447 if (success)
448 success = transaction.Commit();
449 else
450 transaction.Rollback();
451
452 if (!success)
453 ResetDB();
454 }
455
456 void ResourcePrefetchPredictorTables::LogDatabaseStats() {
457 DCHECK_CURRENTLY_ON(BrowserThread::DB);
458 if (CantAccessDatabase())
459 return;
460
461 Statement statement(DB()->GetUniqueStatement(
462 base::StringPrintf("SELECT count(*) FROM %s",
463 kUrlResourceTableName).c_str()));
464 if (statement.Step())
465 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableRowCount",
466 statement.ColumnInt(0));
467
468 statement.Assign(DB()->GetUniqueStatement(
469 base::StringPrintf("SELECT count(*) FROM %s",
470 kHostResourceTableName).c_str()));
471 if (statement.Step())
472 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount",
473 statement.ColumnInt(0));
474 }
475
476 std::unique_ptr<Statement>
477 ResourcePrefetchPredictorTables::GetTableUpdateStatement( 459 ResourcePrefetchPredictorTables::GetTableUpdateStatement(
478 PrefetchKeyType key_type, 460 PrefetchKeyType key_type,
479 PrefetchDataType data_type, 461 PrefetchDataType data_type,
480 TableOperationType op_type) { 462 TableOperationType op_type) {
481 sql::StatementID id(__FILE__, key_type | (static_cast<int>(data_type) << 1) | 463 sql::StatementID id(__FILE__, key_type | (static_cast<int>(data_type) << 1) |
482 (static_cast<int>(op_type) << 2)); 464 (static_cast<int>(op_type) << 2));
483 const char* statement_template = (op_type == TableOperationType::REMOVE 465 const char* statement_template = (op_type == TableOperationType::REMOVE
484 ? kDeleteProtoTableStatementTemplate 466 ? kDeleteProtoTableStatementTemplate
485 : kInsertProtoTableStatementTemplate); 467 : kInsertProtoTableStatementTemplate);
486 const char* table_name = GetTableName(key_type, data_type); 468 const char* table_name = GetTableName(key_type, data_type);
487 return base::MakeUnique<Statement>(DB()->GetCachedStatement( 469 return base::MakeUnique<sql::Statement>(DB()->GetCachedStatement(
488 id, base::StringPrintf(statement_template, table_name).c_str())); 470 id, base::StringPrintf(statement_template, table_name).c_str()));
489 } 471 }
490 472
491 // static 473 // static
492 const char* ResourcePrefetchPredictorTables::GetTableName( 474 const char* ResourcePrefetchPredictorTables::GetTableName(
493 PrefetchKeyType key_type, 475 PrefetchKeyType key_type,
494 PrefetchDataType data_type) { 476 PrefetchDataType data_type) {
495 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 477 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
496 switch (data_type) { 478 switch (data_type) {
497 case PrefetchDataType::RESOURCE: 479 case PrefetchDataType::RESOURCE:
498 return is_host ? kHostResourceTableName : kUrlResourceTableName; 480 return is_host ? kHostResourceTableName : kUrlResourceTableName;
499 case PrefetchDataType::REDIRECT: 481 case PrefetchDataType::REDIRECT:
500 return is_host ? kHostRedirectTableName : kUrlRedirectTableName; 482 return is_host ? kHostRedirectTableName : kUrlRedirectTableName;
501 } 483 }
502 484
503 NOTREACHED(); 485 NOTREACHED();
504 return nullptr; 486 return nullptr;
505 } 487 }
506 488
507 } // namespace predictors 489 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698