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

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

Issue 2321343002: Redirect handling in resource prefetch predictor (Closed)
Patch Set: test Created 4 years, 3 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
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> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "sql/meta_table.h" 17 #include "sql/meta_table.h"
18 #include "sql/statement.h" 18 #include "sql/statement.h"
19 #include "sql/transaction.h" 19 #include "sql/transaction.h"
20 20
21 using content::BrowserThread; 21 using content::BrowserThread;
22 using sql::Statement; 22 using sql::Statement;
23 23
24 namespace { 24 namespace {
25 25
26 using ResourceRow = predictors::ResourcePrefetchPredictorTables::ResourceRow; 26 using ResourceRow = predictors::ResourcePrefetchPredictorTables::ResourceRow;
27 using RedirectStatRow =
28 predictors::ResourcePrefetchPredictorTables::RedirectStatRow;
27 29
28 const char kMetadataTableName[] = "resource_prefetch_predictor_metadata"; 30 const char kMetadataTableName[] = "resource_prefetch_predictor_metadata";
29 const char kUrlResourceTableName[] = "resource_prefetch_predictor_url"; 31 const char kUrlResourceTableName[] = "resource_prefetch_predictor_url";
30 const char kUrlMetadataTableName[] = "resource_prefetch_predictor_url_metadata"; 32 const char kUrlMetadataTableName[] = "resource_prefetch_predictor_url_metadata";
31 const char kHostResourceTableName[] = "resource_prefetch_predictor_host"; 33 const char kHostResourceTableName[] = "resource_prefetch_predictor_host";
32 const char kHostMetadataTableName[] = 34 const char kHostMetadataTableName[] =
33 "resource_prefetch_predictor_host_metadata"; 35 "resource_prefetch_predictor_host_metadata";
34 36
35 const char kCreateGlobalMetadataStatementTemplate[] = 37 const char kCreateGlobalMetadataStatementTemplate[] =
36 "CREATE TABLE %s ( " 38 "CREATE TABLE %s ( "
(...skipping 24 matching lines...) Expand all
61 row.ToProto(&proto); 63 row.ToProto(&proto);
62 int size = proto.ByteSize(); 64 int size = proto.ByteSize();
63 std::vector<char> proto_buffer(size); 65 std::vector<char> proto_buffer(size);
64 proto.SerializeToArray(&proto_buffer[0], size); 66 proto.SerializeToArray(&proto_buffer[0], size);
65 67
66 statement->BindString(0, primary_key); 68 statement->BindString(0, primary_key);
67 statement->BindString(1, row.resource_url.spec()); 69 statement->BindString(1, row.resource_url.spec());
68 statement->BindBlob(2, &proto_buffer[0], size); 70 statement->BindBlob(2, &proto_buffer[0], size);
69 } 71 }
70 72
73 void BindRedirectStatRowToStatement(const RedirectStatRow& row,
74 const std::string& primary_key,
75 Statement* statement) {
76
77 }
78
71 bool StepAndInitializeResourceRow(Statement* statement, 79 bool StepAndInitializeResourceRow(Statement* statement,
72 ResourceRow* row, 80 ResourceRow* row,
73 std::string* primary_key) { 81 std::string* primary_key) {
74 if (!statement->Step()) 82 if (!statement->Step())
75 return false; 83 return false;
76 84
77 *primary_key = statement->ColumnString(0); 85 *primary_key = statement->ColumnString(0);
78 86
79 int size = statement->ColumnByteLength(2); 87 int size = statement->ColumnByteLength(2);
80 const void* data = statement->ColumnBlob(2); 88 const void* data = statement->ColumnBlob(2);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 232
225 ResourcePrefetchPredictorTables::PrefetchData::~PrefetchData() { 233 ResourcePrefetchPredictorTables::PrefetchData::~PrefetchData() {
226 } 234 }
227 235
228 bool ResourcePrefetchPredictorTables::PrefetchData::operator==( 236 bool ResourcePrefetchPredictorTables::PrefetchData::operator==(
229 const PrefetchData& rhs) const { 237 const PrefetchData& rhs) const {
230 return key_type == rhs.key_type && primary_key == rhs.primary_key && 238 return key_type == rhs.key_type && primary_key == rhs.primary_key &&
231 resources == rhs.resources; 239 resources == rhs.resources;
232 } 240 }
233 241
242 RedirectStatRow::RedirectStatRow()
243 : number_of_hits(0),
244 number_of_misses(0),
245 consecutive_misses(0) {}
246
247 RedirectStatRow::RedirectStatRow(const RedirectStatRow& other)
248 : final_redirect(other.final_redirect),
249 number_of_hits(other.number_of_hits),
250 number_of_misses(other.number_of_misses),
251 consecutive_misses(other.consecutive_misses) {}
252
253 ResourcePrefetchPredictorTables::RedirectData::RedirectData(
254 PrefetchKeyType i_key_type,
255 const std::string& i_primary_key)
256 : key_type(i_key_type),
257 primary_key(i_primary_key) {}
258
259 ResourcePrefetchPredictorTables::RedirectData::RedirectData(
260 const RedirectData& other)
261 : key_type(other.key_type),
262 primary_key(other.primary_key),
263 last_visit(other.last_visit),
264 redirect_stats(other.redirect_stats) {}
265
266 ResourcePrefetchPredictorTables::RedirectData::~RedirectData() {
267 }
268
234 void ResourcePrefetchPredictorTables::GetAllData( 269 void ResourcePrefetchPredictorTables::GetAllData(
235 PrefetchDataMap* url_data_map, 270 PrefetchDataMap* url_data_map,
236 PrefetchDataMap* host_data_map) { 271 PrefetchDataMap* host_data_map,
272 RedirectDataMap* url_redirect_data_map,
273 RedirectDataMap* host_redirect_data_map) {
237 DCHECK_CURRENTLY_ON(BrowserThread::DB); 274 DCHECK_CURRENTLY_ON(BrowserThread::DB);
238 if (CantAccessDatabase()) 275 if (CantAccessDatabase())
239 return; 276 return;
240 277
241 DCHECK(url_data_map); 278 DCHECK(url_data_map);
242 DCHECK(host_data_map); 279 DCHECK(host_data_map);
280 DCHECK(url_redirect_data_map);
281 DCHECK(host_redirect_data_map);
243 url_data_map->clear(); 282 url_data_map->clear();
244 host_data_map->clear(); 283 host_data_map->clear();
284 url_redirect_data_map->clear();
285 host_redirect_data_map->clear();
245 286
246 std::vector<std::string> urls_to_delete, hosts_to_delete; 287 std::vector<std::string> urls_to_delete, hosts_to_delete;
247 GetAllDataHelper(PREFETCH_KEY_TYPE_URL, url_data_map, &urls_to_delete); 288 GetAllDataHelper(PREFETCH_KEY_TYPE_URL, url_data_map, &urls_to_delete);
248 GetAllDataHelper(PREFETCH_KEY_TYPE_HOST, host_data_map, &hosts_to_delete); 289 GetAllDataHelper(PREFETCH_KEY_TYPE_HOST, host_data_map, &hosts_to_delete);
290 // TODO: get data from redirect tables
249 291
250 if (!urls_to_delete.empty() || !hosts_to_delete.empty()) 292 if (!urls_to_delete.empty() || !hosts_to_delete.empty())
251 DeleteData(urls_to_delete, hosts_to_delete); 293 DeleteData(urls_to_delete, hosts_to_delete);
252 } 294 }
253 295
254 void ResourcePrefetchPredictorTables::UpdateData( 296 void ResourcePrefetchPredictorTables::UpdatePrefetchData(
255 const PrefetchData& url_data, 297 const PrefetchData& url_data,
256 const PrefetchData& host_data) { 298 const PrefetchData& host_data) {
257 DCHECK_CURRENTLY_ON(BrowserThread::DB); 299 DCHECK_CURRENTLY_ON(BrowserThread::DB);
258 if (CantAccessDatabase()) 300 if (CantAccessDatabase())
259 return; 301 return;
260 302
261 DCHECK(!url_data.is_host() && host_data.is_host()); 303 DCHECK(!url_data.is_host() && host_data.is_host());
262 DCHECK(!url_data.primary_key.empty() || !host_data.primary_key.empty()); 304 DCHECK(!url_data.primary_key.empty() || !host_data.primary_key.empty());
263 305
264 DB()->BeginTransaction(); 306 DB()->BeginTransaction();
265 307
266 bool success = (url_data.primary_key.empty() || UpdateDataHelper(url_data)) && 308 bool success =
309 (url_data.primary_key.empty() || UpdatePrefetchDataHelper(url_data)) &&
267 (host_data.primary_key.empty() || UpdateDataHelper(host_data)); 310 (host_data.primary_key.empty() || UpdateDataHelper(host_data));
268 if (!success) 311 if (!success)
269 DB()->RollbackTransaction(); 312 DB()->RollbackTransaction();
270 313
271 DB()->CommitTransaction(); 314 DB()->CommitTransaction();
272 } 315 }
273 316
317 void ResourcePrefetchPredictorTables::UpdateRedirectData(
318 const RedirectData& redirect_data) {
319 DCHECK_CURRENTLY_ON(BrowserThread::DB);
320 if (CantAccessDatabase())
321 return;
322
323 DB()->BeginTransaction();
324
325 bool success = UpdateRedirectDataHelper(redirect_data);
326 if (!success)
327 DB()->RollbackTransaction();
328
329 DB()->CommitTransaction();
330 }
331
274 void ResourcePrefetchPredictorTables::DeleteData( 332 void ResourcePrefetchPredictorTables::DeleteData(
275 const std::vector<std::string>& urls, 333 const std::vector<std::string>& urls,
276 const std::vector<std::string>& hosts) { 334 const std::vector<std::string>& hosts) {
277 DCHECK_CURRENTLY_ON(BrowserThread::DB); 335 DCHECK_CURRENTLY_ON(BrowserThread::DB);
278 if (CantAccessDatabase()) 336 if (CantAccessDatabase())
279 return; 337 return;
280 338
281 DCHECK(!urls.empty() || !hosts.empty()); 339 DCHECK(!urls.empty() || !hosts.empty());
282 340
283 if (!urls.empty()) 341 if (!urls.empty())
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 PrefetchDataMap::iterator it = data_map->find(primary_key); 415 PrefetchDataMap::iterator it = data_map->find(primary_key);
358 if (it != data_map->end()) { 416 if (it != data_map->end()) {
359 int64_t last_visit = metadata_reader.ColumnInt64(1); 417 int64_t last_visit = metadata_reader.ColumnInt64(1);
360 it->second.last_visit = base::Time::FromInternalValue(last_visit); 418 it->second.last_visit = base::Time::FromInternalValue(last_visit);
361 } else { 419 } else {
362 to_delete->push_back(primary_key); 420 to_delete->push_back(primary_key);
363 } 421 }
364 } 422 }
365 } 423 }
366 424
367 bool ResourcePrefetchPredictorTables::UpdateDataHelper( 425 bool ResourcePrefetchPredictorTables::UpdatePrefetchDataHelper(
368 const PrefetchData& data) { 426 const PrefetchData& data) {
369 DCHECK(!data.primary_key.empty()); 427 DCHECK(!data.primary_key.empty());
370 428
371 if (!StringsAreSmallerThanDBLimit(data)) { 429 if (!StringsAreSmallerThanDBLimit(data)) {
372 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true); 430 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
373 return false; 431 return false;
374 } 432 }
375 433
376 // Delete the older data from both the tables. 434 // Delete the older data from both the tables.
377 std::unique_ptr<Statement> deleter(data.is_host() 435 std::unique_ptr<Statement> deleter(data.is_host()
(...skipping 24 matching lines...) Expand all
402 data.is_host() ? GetHostMetadataUpdateStatement() 460 data.is_host() ? GetHostMetadataUpdateStatement()
403 : GetUrlMetadataUpdateStatement()); 461 : GetUrlMetadataUpdateStatement());
404 metadata_inserter->BindString(0, data.primary_key); 462 metadata_inserter->BindString(0, data.primary_key);
405 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue()); 463 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue());
406 if (!metadata_inserter->Run()) 464 if (!metadata_inserter->Run())
407 return false; 465 return false;
408 466
409 return true; 467 return true;
410 } 468 }
411 469
470 bool ResourcePrefetchPredictorTables::UpdateRedirectDataHelper(
471 const RedirectData& data) {
472 DCHECK(!data.primary_key.empty());
473
474 if (!StringsAreSmallerThanDBLimit(data)) {
475 // TODO: UMA?
mattcary 2016/09/09 13:19:21 Yes!
476 return false;
477 }
478
479 // Delete the older data from the table.
480 std::unique_ptr<Statement> deleter(data.is_host()
481 ? GetHostRedirectStatDeleteStatement()
482 : GetUrlRedirectStatDeleteStatement());
483 deleter->BindString(0, data.primary_key);
484 if (!deleter->Run())
485 return false;
486
487 // Add the new data to the table.
488 for (const RedirectStatRow& row : data.redirect_stats) {
489 std::unique_ptr<Statement> row_inserter(
490 data.is_host() ? GetHostRedirectStatUpdateStatement()
491 : GetUrlRedirectStatUpdateStatement());
492 BindRedirectStatRowToStatement(row, data.primary_key, row_inserter.get());
493 if (!row_inserter->Run())
494 return false;
495 }
496
497 return true;
498 }
499
412 void ResourcePrefetchPredictorTables::DeleteDataHelper( 500 void ResourcePrefetchPredictorTables::DeleteDataHelper(
413 PrefetchKeyType key_type, 501 PrefetchKeyType key_type,
414 const std::vector<std::string>& keys) { 502 const std::vector<std::string>& keys) {
415 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 503 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
416 504
417 for (const std::string& key : keys) { 505 for (const std::string& key : keys) {
418 std::unique_ptr<Statement> deleter(is_host 506 std::unique_ptr<Statement> deleter(is_host
419 ? GetHostResourceDeleteStatement() 507 ? GetHostResourceDeleteStatement()
420 : GetUrlResourceDeleteStatement()); 508 : GetUrlResourceDeleteStatement());
421 deleter->BindString(0, key); 509 deleter->BindString(0, key);
(...skipping 13 matching lines...) Expand all
435 return false; 523 return false;
436 524
437 for (const ResourceRow& row : data.resources) { 525 for (const ResourceRow& row : data.resources) {
438 if (row.resource_url.spec().length() > kMaxStringLength) 526 if (row.resource_url.spec().length() > kMaxStringLength)
439 return false; 527 return false;
440 } 528 }
441 return true; 529 return true;
442 } 530 }
443 531
444 // static 532 // static
533 bool ResourcePrefetchPredictorTables::StringAreSmallerThanDBLimit(
534 const RedirectData& data) {
535 if (data.primary_key.length() > kMaxStringLength)
536 return false;
537
538 for (const RedirectStatRow& row : data.redirect_stats) {
539 if (row.final_redirect.length() > kMaxStringLength)
540 return false;
541 }
542 return true;
543 }
544
545 // static
445 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( 546 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated(
446 sql::Connection* db) { 547 sql::Connection* db) {
447 int version = GetDatabaseVersion(db); 548 int version = GetDatabaseVersion(db);
448 bool success = true; 549 bool success = true;
449 // Too new is also a problem. 550 // Too new is also a problem.
450 bool incompatible_version = version != kDatabaseVersion; 551 bool incompatible_version = version != kDatabaseVersion;
451 552
452 if (incompatible_version) { 553 if (incompatible_version) {
453 for (const char* table_name : 554 for (const char* table_name :
454 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName, 555 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName,
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 } 715 }
615 716
616 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() { 717 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() {
617 return new Statement(DB()->GetCachedStatement( 718 return new Statement(DB()->GetCachedStatement(
618 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, 719 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate,
619 kHostMetadataTableName) 720 kHostMetadataTableName)
620 .c_str())); 721 .c_str()));
621 } 722 }
622 723
623 } // namespace predictors 724 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698