| OLD | NEW |
| 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> |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 const predictors::ResourcePrefetchPredictorTables::ResourceRow& row, | 31 const predictors::ResourcePrefetchPredictorTables::ResourceRow& row, |
| 32 const std::string& primary_key, | 32 const std::string& primary_key, |
| 33 Statement* statement) { | 33 Statement* statement) { |
| 34 statement->BindString(0, primary_key); | 34 statement->BindString(0, primary_key); |
| 35 statement->BindString(1, row.resource_url.spec()); | 35 statement->BindString(1, row.resource_url.spec()); |
| 36 statement->BindInt(2, static_cast<int>(row.resource_type)); | 36 statement->BindInt(2, static_cast<int>(row.resource_type)); |
| 37 statement->BindInt(3, row.number_of_hits); | 37 statement->BindInt(3, row.number_of_hits); |
| 38 statement->BindInt(4, row.number_of_misses); | 38 statement->BindInt(4, row.number_of_misses); |
| 39 statement->BindInt(5, row.consecutive_misses); | 39 statement->BindInt(5, row.consecutive_misses); |
| 40 statement->BindDouble(6, row.average_position); | 40 statement->BindDouble(6, row.average_position); |
| 41 statement->BindInt(7, static_cast<int>(row.priority)); |
| 41 } | 42 } |
| 42 | 43 |
| 43 bool StepAndInitializeResourceRow( | 44 bool StepAndInitializeResourceRow( |
| 44 Statement* statement, | 45 Statement* statement, |
| 45 predictors::ResourcePrefetchPredictorTables::ResourceRow* row) { | 46 predictors::ResourcePrefetchPredictorTables::ResourceRow* row) { |
| 46 if (!statement->Step()) | 47 if (!statement->Step()) |
| 47 return false; | 48 return false; |
| 48 | 49 |
| 49 row->primary_key = statement->ColumnString(0); | 50 row->primary_key = statement->ColumnString(0); |
| 50 row->resource_url = GURL(statement->ColumnString(1)); | 51 row->resource_url = GURL(statement->ColumnString(1)); |
| 51 row->resource_type = static_cast<content::ResourceType>( | 52 row->resource_type = static_cast<content::ResourceType>( |
| 52 statement->ColumnInt(2)); | 53 statement->ColumnInt(2)); |
| 53 row->number_of_hits = statement->ColumnInt(3); | 54 row->number_of_hits = statement->ColumnInt(3); |
| 54 row->number_of_misses = statement->ColumnInt(4); | 55 row->number_of_misses = statement->ColumnInt(4); |
| 55 row->consecutive_misses = statement->ColumnInt(5); | 56 row->consecutive_misses = statement->ColumnInt(5); |
| 56 row->average_position = statement->ColumnDouble(6); | 57 row->average_position = statement->ColumnDouble(6); |
| 58 row->priority = static_cast<net::RequestPriority>(statement->ColumnInt(7)); |
| 57 return true; | 59 return true; |
| 58 } | 60 } |
| 59 | 61 |
| 60 } // namespace | 62 } // namespace |
| 61 | 63 |
| 62 namespace predictors { | 64 namespace predictors { |
| 63 | 65 |
| 64 // static | 66 // static |
| 65 const size_t ResourcePrefetchPredictorTables::kMaxStringLength = 1024; | 67 const size_t ResourcePrefetchPredictorTables::kMaxStringLength = 1024; |
| 66 | 68 |
| 67 ResourcePrefetchPredictorTables::ResourceRow::ResourceRow() | 69 ResourcePrefetchPredictorTables::ResourceRow::ResourceRow() |
| 68 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), | 70 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), |
| 69 number_of_hits(0), | 71 number_of_hits(0), |
| 70 number_of_misses(0), | 72 number_of_misses(0), |
| 71 consecutive_misses(0), | 73 consecutive_misses(0), |
| 72 average_position(0.0), | 74 average_position(0.0), |
| 73 score(0.0) { | 75 priority(net::IDLE), |
| 74 } | 76 score(0.0) {} |
| 75 | 77 |
| 76 ResourcePrefetchPredictorTables::ResourceRow::ResourceRow( | 78 ResourcePrefetchPredictorTables::ResourceRow::ResourceRow( |
| 77 const ResourceRow& other) | 79 const ResourceRow& other) |
| 78 : primary_key(other.primary_key), | 80 : primary_key(other.primary_key), |
| 79 resource_url(other.resource_url), | 81 resource_url(other.resource_url), |
| 80 resource_type(other.resource_type), | 82 resource_type(other.resource_type), |
| 81 number_of_hits(other.number_of_hits), | 83 number_of_hits(other.number_of_hits), |
| 82 number_of_misses(other.number_of_misses), | 84 number_of_misses(other.number_of_misses), |
| 83 consecutive_misses(other.consecutive_misses), | 85 consecutive_misses(other.consecutive_misses), |
| 84 average_position(other.average_position), | 86 average_position(other.average_position), |
| 85 score(other.score) { | 87 priority(other.priority), |
| 86 } | 88 score(other.score) {} |
| 87 | 89 |
| 88 ResourcePrefetchPredictorTables::ResourceRow::ResourceRow( | 90 ResourcePrefetchPredictorTables::ResourceRow::ResourceRow( |
| 89 const std::string& i_primary_key, | 91 const std::string& i_primary_key, |
| 90 const std::string& i_resource_url, | 92 const std::string& i_resource_url, |
| 91 content::ResourceType i_resource_type, | 93 content::ResourceType i_resource_type, |
| 92 int i_number_of_hits, | 94 int i_number_of_hits, |
| 93 int i_number_of_misses, | 95 int i_number_of_misses, |
| 94 int i_consecutive_misses, | 96 int i_consecutive_misses, |
| 95 double i_average_position) | 97 double i_average_position, |
| 96 : primary_key(i_primary_key), | 98 net::RequestPriority i_priority) |
| 97 resource_url(i_resource_url), | 99 : primary_key(i_primary_key), |
| 98 resource_type(i_resource_type), | 100 resource_url(i_resource_url), |
| 99 number_of_hits(i_number_of_hits), | 101 resource_type(i_resource_type), |
| 100 number_of_misses(i_number_of_misses), | 102 number_of_hits(i_number_of_hits), |
| 101 consecutive_misses(i_consecutive_misses), | 103 number_of_misses(i_number_of_misses), |
| 102 average_position(i_average_position) { | 104 consecutive_misses(i_consecutive_misses), |
| 105 average_position(i_average_position), |
| 106 priority(i_priority) { |
| 103 UpdateScore(); | 107 UpdateScore(); |
| 104 } | 108 } |
| 105 | 109 |
| 106 void ResourcePrefetchPredictorTables::ResourceRow::UpdateScore() { | 110 void ResourcePrefetchPredictorTables::ResourceRow::UpdateScore() { |
| 107 // The score is calculated so that when the rows are sorted, stylesheets, | 111 // The score is calculated so that when the rows are sorted, stylesheets, |
| 108 // scripts and fonts appear first, sorted by position(ascending) and then the | 112 // scripts and fonts appear first, sorted by position(ascending) and then the |
| 109 // rest of the resources sorted by position (ascending). | 113 // rest of the resources sorted by position (ascending). |
| 110 static const int kMaxResourcesPerType = 100; | 114 static const int kMaxResourcesPerType = 100; |
| 111 switch (resource_type) { | 115 switch (resource_type) { |
| 112 case content::RESOURCE_TYPE_STYLESHEET: | 116 case content::RESOURCE_TYPE_STYLESHEET: |
| 113 case content::RESOURCE_TYPE_SCRIPT: | 117 case content::RESOURCE_TYPE_SCRIPT: |
| 114 case content::RESOURCE_TYPE_FONT_RESOURCE: | 118 case content::RESOURCE_TYPE_FONT_RESOURCE: |
| 115 score = (2 * kMaxResourcesPerType) - average_position; | 119 score = (2 * kMaxResourcesPerType) - average_position; |
| 116 break; | 120 break; |
| 117 | 121 |
| 118 case content::RESOURCE_TYPE_IMAGE: | 122 case content::RESOURCE_TYPE_IMAGE: |
| 119 default: | 123 default: |
| 120 score = kMaxResourcesPerType - average_position; | 124 score = kMaxResourcesPerType - average_position; |
| 121 break; | 125 break; |
| 122 } | 126 } |
| 127 // TODO(lizeb): Take priority into account. |
| 123 } | 128 } |
| 124 | 129 |
| 125 bool ResourcePrefetchPredictorTables::ResourceRow::operator==( | 130 bool ResourcePrefetchPredictorTables::ResourceRow::operator==( |
| 126 const ResourceRow& rhs) const { | 131 const ResourceRow& rhs) const { |
| 127 return primary_key == rhs.primary_key && | 132 return primary_key == rhs.primary_key && resource_url == rhs.resource_url && |
| 128 resource_url == rhs.resource_url && | 133 resource_type == rhs.resource_type && |
| 129 resource_type == rhs.resource_type && | 134 number_of_hits == rhs.number_of_hits && |
| 130 number_of_hits == rhs.number_of_hits && | 135 number_of_misses == rhs.number_of_misses && |
| 131 number_of_misses == rhs.number_of_misses && | 136 consecutive_misses == rhs.consecutive_misses && |
| 132 consecutive_misses == rhs.consecutive_misses && | 137 average_position == rhs.average_position && priority == rhs.priority && |
| 133 average_position == rhs.average_position && | 138 score == rhs.score; |
| 134 score == rhs.score; | |
| 135 } | 139 } |
| 136 | 140 |
| 137 bool ResourcePrefetchPredictorTables::ResourceRowSorter::operator()( | 141 bool ResourcePrefetchPredictorTables::ResourceRowSorter::operator()( |
| 138 const ResourceRow& x, const ResourceRow& y) const { | 142 const ResourceRow& x, const ResourceRow& y) const { |
| 139 return x.score > y.score; | 143 return x.score > y.score; |
| 140 } | 144 } |
| 141 | 145 |
| 142 ResourcePrefetchPredictorTables::PrefetchData::PrefetchData( | 146 ResourcePrefetchPredictorTables::PrefetchData::PrefetchData( |
| 143 PrefetchKeyType i_key_type, | 147 PrefetchKeyType i_key_type, |
| 144 const std::string& i_primary_key) | 148 const std::string& i_primary_key) |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 return false; | 384 return false; |
| 381 | 385 |
| 382 for (ResourceRows::const_iterator it = data.resources.begin(); | 386 for (ResourceRows::const_iterator it = data.resources.begin(); |
| 383 it != data.resources.end(); ++it) { | 387 it != data.resources.end(); ++it) { |
| 384 if (it->resource_url.spec().length() > kMaxStringLength) | 388 if (it->resource_url.spec().length() > kMaxStringLength) |
| 385 return false; | 389 return false; |
| 386 } | 390 } |
| 387 return true; | 391 return true; |
| 388 } | 392 } |
| 389 | 393 |
| 394 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( |
| 395 sql::Connection* db) { |
| 396 bool success = true; |
| 397 for (const char* table_name : |
| 398 {kUrlResourceTableName, kHostResourceTableName}) { |
| 399 if (db->DoesTableExist(table_name) && |
| 400 !db->DoesColumnExist(table_name, "priority")) { |
| 401 success &= |
| 402 db->Execute(base::StringPrintf("DROP TABLE %s", table_name).c_str()); |
| 403 } |
| 404 } |
| 405 return success; |
| 406 } |
| 407 |
| 390 void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() { | 408 void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() { |
| 391 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 409 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 392 if (CantAccessDatabase()) | 410 if (CantAccessDatabase()) |
| 393 return; | 411 return; |
| 394 | 412 |
| 395 const char resource_table_creator[] = | 413 const char resource_table_creator[] = |
| 396 "CREATE TABLE %s ( " | 414 "CREATE TABLE %s ( " |
| 397 "main_page_url TEXT, " | 415 "main_page_url TEXT, " |
| 398 "resource_url TEXT, " | 416 "resource_url TEXT, " |
| 399 "resource_type INTEGER, " | 417 "resource_type INTEGER, " |
| 400 "number_of_hits INTEGER, " | 418 "number_of_hits INTEGER, " |
| 401 "number_of_misses INTEGER, " | 419 "number_of_misses INTEGER, " |
| 402 "consecutive_misses INTEGER, " | 420 "consecutive_misses INTEGER, " |
| 403 "average_position DOUBLE, " | 421 "average_position DOUBLE, " |
| 422 "priority INTEGER, " |
| 404 "PRIMARY KEY(main_page_url, resource_url))"; | 423 "PRIMARY KEY(main_page_url, resource_url))"; |
| 405 const char* metadata_table_creator = | 424 const char* metadata_table_creator = |
| 406 "CREATE TABLE %s ( " | 425 "CREATE TABLE %s ( " |
| 407 "main_page_url TEXT, " | 426 "main_page_url TEXT, " |
| 408 "last_visit_time INTEGER, " | 427 "last_visit_time INTEGER, " |
| 409 "PRIMARY KEY(main_page_url))"; | 428 "PRIMARY KEY(main_page_url))"; |
| 410 | 429 |
| 411 sql::Connection* db = DB(); | 430 sql::Connection* db = DB(); |
| 412 bool success = | 431 bool success = DropTablesIfOutdated(db) && |
| 413 (db->DoesTableExist(kUrlResourceTableName) || | 432 (db->DoesTableExist(kUrlResourceTableName) || |
| 414 db->Execute(base::StringPrintf(resource_table_creator, | 433 db->Execute(base::StringPrintf(resource_table_creator, |
| 415 kUrlResourceTableName).c_str())) && | 434 kUrlResourceTableName) |
| 416 (db->DoesTableExist(kUrlMetadataTableName) || | 435 .c_str())) && |
| 417 db->Execute(base::StringPrintf(metadata_table_creator, | 436 (db->DoesTableExist(kUrlMetadataTableName) || |
| 418 kUrlMetadataTableName).c_str())) && | 437 db->Execute(base::StringPrintf(metadata_table_creator, |
| 419 (db->DoesTableExist(kHostResourceTableName) || | 438 kUrlMetadataTableName) |
| 420 db->Execute(base::StringPrintf(resource_table_creator, | 439 .c_str())) && |
| 421 kHostResourceTableName).c_str())) && | 440 (db->DoesTableExist(kHostResourceTableName) || |
| 422 (db->DoesTableExist(kHostMetadataTableName) || | 441 db->Execute(base::StringPrintf(resource_table_creator, |
| 423 db->Execute(base::StringPrintf(metadata_table_creator, | 442 kHostResourceTableName) |
| 424 kHostMetadataTableName).c_str())); | 443 .c_str())) && |
| 444 (db->DoesTableExist(kHostMetadataTableName) || |
| 445 db->Execute(base::StringPrintf(metadata_table_creator, |
| 446 kHostMetadataTableName) |
| 447 .c_str())); |
| 425 | 448 |
| 426 if (!success) | 449 if (!success) |
| 427 ResetDB(); | 450 ResetDB(); |
| 428 } | 451 } |
| 429 | 452 |
| 430 void ResourcePrefetchPredictorTables::LogDatabaseStats() { | 453 void ResourcePrefetchPredictorTables::LogDatabaseStats() { |
| 431 DCHECK_CURRENTLY_ON(BrowserThread::DB); | 454 DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| 432 if (CantAccessDatabase()) | 455 if (CantAccessDatabase()) |
| 433 return; | 456 return; |
| 434 | 457 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 455 kUrlResourceTableName).c_str())); | 478 kUrlResourceTableName).c_str())); |
| 456 } | 479 } |
| 457 | 480 |
| 458 Statement* | 481 Statement* |
| 459 ResourcePrefetchPredictorTables::GetUrlResourceUpdateStatement() { | 482 ResourcePrefetchPredictorTables::GetUrlResourceUpdateStatement() { |
| 460 return new Statement(DB()->GetCachedStatement( | 483 return new Statement(DB()->GetCachedStatement( |
| 461 SQL_FROM_HERE, | 484 SQL_FROM_HERE, |
| 462 base::StringPrintf( | 485 base::StringPrintf( |
| 463 "INSERT INTO %s " | 486 "INSERT INTO %s " |
| 464 "(main_page_url, resource_url, resource_type, number_of_hits, " | 487 "(main_page_url, resource_url, resource_type, number_of_hits, " |
| 465 "number_of_misses, consecutive_misses, average_position) " | 488 "number_of_misses, consecutive_misses, average_position, priority) " |
| 466 "VALUES (?,?,?,?,?,?,?)", kUrlResourceTableName).c_str())); | 489 "VALUES (?,?,?,?,?,?,?,?)", |
| 490 kUrlResourceTableName) |
| 491 .c_str())); |
| 467 } | 492 } |
| 468 | 493 |
| 469 Statement* | 494 Statement* |
| 470 ResourcePrefetchPredictorTables::GetUrlMetadataDeleteStatement() { | 495 ResourcePrefetchPredictorTables::GetUrlMetadataDeleteStatement() { |
| 471 return new Statement(DB()->GetCachedStatement( | 496 return new Statement(DB()->GetCachedStatement( |
| 472 SQL_FROM_HERE, | 497 SQL_FROM_HERE, |
| 473 base::StringPrintf("DELETE FROM %s WHERE main_page_url=?", | 498 base::StringPrintf("DELETE FROM %s WHERE main_page_url=?", |
| 474 kUrlMetadataTableName).c_str())); | 499 kUrlMetadataTableName).c_str())); |
| 475 } | 500 } |
| 476 | 501 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 491 kHostResourceTableName).c_str())); | 516 kHostResourceTableName).c_str())); |
| 492 } | 517 } |
| 493 | 518 |
| 494 Statement* | 519 Statement* |
| 495 ResourcePrefetchPredictorTables::GetHostResourceUpdateStatement() { | 520 ResourcePrefetchPredictorTables::GetHostResourceUpdateStatement() { |
| 496 return new Statement(DB()->GetCachedStatement( | 521 return new Statement(DB()->GetCachedStatement( |
| 497 SQL_FROM_HERE, | 522 SQL_FROM_HERE, |
| 498 base::StringPrintf( | 523 base::StringPrintf( |
| 499 "INSERT INTO %s " | 524 "INSERT INTO %s " |
| 500 "(main_page_url, resource_url, resource_type, number_of_hits, " | 525 "(main_page_url, resource_url, resource_type, number_of_hits, " |
| 501 "number_of_misses, consecutive_misses, average_position) " | 526 "number_of_misses, consecutive_misses, average_position, priority) " |
| 502 "VALUES (?,?,?,?,?,?,?)", kHostResourceTableName).c_str())); | 527 "VALUES (?,?,?,?,?,?,?,?)", |
| 528 kHostResourceTableName) |
| 529 .c_str())); |
| 503 } | 530 } |
| 504 | 531 |
| 505 Statement* | 532 Statement* |
| 506 ResourcePrefetchPredictorTables::GetHostMetadataDeleteStatement() { | 533 ResourcePrefetchPredictorTables::GetHostMetadataDeleteStatement() { |
| 507 return new Statement(DB()->GetCachedStatement( | 534 return new Statement(DB()->GetCachedStatement( |
| 508 SQL_FROM_HERE, | 535 SQL_FROM_HERE, |
| 509 base::StringPrintf("DELETE FROM %s WHERE main_page_url=?", | 536 base::StringPrintf("DELETE FROM %s WHERE main_page_url=?", |
| 510 kHostMetadataTableName).c_str())); | 537 kHostMetadataTableName).c_str())); |
| 511 } | 538 } |
| 512 | 539 |
| 513 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() { | 540 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() { |
| 514 return new Statement(DB()->GetCachedStatement( | 541 return new Statement(DB()->GetCachedStatement( |
| 515 SQL_FROM_HERE, | 542 SQL_FROM_HERE, |
| 516 base::StringPrintf( | 543 base::StringPrintf( |
| 517 "INSERT INTO %s (main_page_url, last_visit_time) VALUES (?,?)", | 544 "INSERT INTO %s (main_page_url, last_visit_time) VALUES (?,?)", |
| 518 kHostMetadataTableName).c_str())); | 545 kHostMetadataTableName).c_str())); |
| 519 } | 546 } |
| 520 | 547 |
| 521 } // namespace predictors | 548 } // namespace predictors |
| OLD | NEW |