Chromium Code Reviews| Index: chrome/browser/predictors/resource_prefetch_predictor_tables.cc |
| diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc |
| index 75cfb3942947b5820fb761d5309cb80159e00c25..fda72737da2761d04c4e9d4c6db21c63ee11f6d5 100644 |
| --- a/chrome/browser/predictors/resource_prefetch_predictor_tables.cc |
| +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables.cc |
| @@ -24,13 +24,23 @@ using sql::Statement; |
| namespace { |
| using ResourceRow = predictors::ResourcePrefetchPredictorTables::ResourceRow; |
| +using RedirectRow = predictors::ResourcePrefetchPredictorTables::RedirectRow; |
| const char kMetadataTableName[] = "resource_prefetch_predictor_metadata"; |
| -const char kUrlResourceTableName[] = "resource_prefetch_predictor_url"; |
| -const char kUrlMetadataTableName[] = "resource_prefetch_predictor_url_metadata"; |
| -const char kHostResourceTableName[] = "resource_prefetch_predictor_host"; |
| -const char kHostMetadataTableName[] = |
| - "resource_prefetch_predictor_host_metadata"; |
| +const char kUrlResourceTableName[] = "resource_prefetch_predictor_url_resource"; |
| +const char kUrlResourceMetadataTableName[] = |
| + "resource_prefetch_predictor_url_resource_metadata"; |
| +const char kUrlRedirectTableName[] = "resource_prefetch_predictor_url_redirect"; |
| +const char kUrlRedirectMetadataTableName[] = |
| + "resource_prefetch_predictor_url_redirect_metadata"; |
| +const char kHostResourceTableName[] = |
| + "resource_prefetch_predictor_host_resource"; |
| +const char kHostResourceMetadataTableName[] = |
| + "resource_prefetch_predictor_host_resource_metadata"; |
| +const char kHostRedirectTableName[] = |
| + "resource_prefetch_predictor_host_redirect"; |
| +const char kHostRedirectMetadataTableName[] = |
| + "resource_prefetch_preditcor_host_redirect_metadata"; |
| const char kCreateGlobalMetadataStatementTemplate[] = |
| "CREATE TABLE %s ( " |
| @@ -42,6 +52,12 @@ const char kCreateResourceTableStatementTemplate[] = |
| "resource_url TEXT, " |
| "proto BLOB, " |
| "PRIMARY KEY(main_page_url, resource_url))"; |
| +const char kCreateRedirectTableStatementTemplate[] = |
| + "CREATE TABLE %s ( " |
| + "main_page_url TEXT, " |
| + "final_redirect TEXT, " |
|
mattcary
2016/09/14 15:37:09
I'm not sure why final_redirect is part of the key
alexilin
2016/09/14 18:59:55
I just copied structure of resource table. It's a
mattcary
2016/09/15 09:04:34
Yeah, that's what I mean. If you always change mul
|
| + "proto BLOB, " |
| + "PRIMARY KEY(main_page_url, final_redirect))"; |
| const char kCreateMetadataTableStatementTemplate[] = |
| "CREATE TABLE %s ( " |
| "main_page_url TEXT, " |
| @@ -50,6 +66,8 @@ const char kCreateMetadataTableStatementTemplate[] = |
| const char kInsertResourceTableStatementTemplate[] = |
| "INSERT INTO %s (main_page_url, resource_url, proto) VALUES (?,?,?)"; |
| +const char kInsertRedirectTableStatementTemplate[] = |
| + "INSERT INTO %s (main_page_url, final_redirect, proto) VALUES (?,?,?)"; |
| const char kInsertMetadataTableStatementTemplate[] = |
| "INSERT INTO %s (main_page_url, last_visit_time) VALUES (?,?)"; |
| const char kDeleteStatementTemplate[] = "DELETE FROM %s WHERE main_page_url=?"; |
| @@ -68,6 +86,20 @@ void BindResourceRowToStatement(const ResourceRow& row, |
| statement->BindBlob(2, &proto_buffer[0], size); |
| } |
| +void BindRedirectRowToStatement(const RedirectRow& row, |
| + const std::string& primary_key, |
| + Statement* statement) { |
| + chrome_browser_predictors::RedirectStat proto; |
| + row.ToProto(&proto); |
| + int size = proto.ByteSize(); |
| + std::vector<char> proto_buffer(size); |
| + proto.SerializeToArray(&proto_buffer[0], size); |
| + |
| + statement->BindString(0, primary_key); |
| + statement->BindString(1, row.final_redirect); |
| + statement->BindBlob(2, &proto_buffer[0], size); |
| +} |
| + |
| bool StepAndInitializeResourceRow(Statement* statement, |
| ResourceRow* row, |
| std::string* primary_key) { |
| @@ -89,6 +121,27 @@ bool StepAndInitializeResourceRow(Statement* statement, |
| return true; |
| } |
| +bool StepAndInitializeRedirectRow(Statement* statement, |
| + RedirectRow* row, |
| + std::string* primary_key) { |
| + if (!statement->Step()) |
| + return false; |
| + |
| + *primary_key = statement->ColumnString(0); |
| + |
| + int size = statement->ColumnByteLength(2); |
| + const void* data = statement->ColumnBlob(2); |
| + DCHECK(data); |
| + chrome_browser_predictors::RedirectStat proto; |
| + proto.ParseFromArray(data, size); |
| + RedirectRow::FromProto(proto, row); |
| + |
| + std::string final_redirect(statement->ColumnString(1)); |
| + DCHECK(final_redirect == row->final_redirect); |
| + |
| + return true; |
| +} |
| + |
| } // namespace |
| namespace predictors { |
| @@ -168,6 +221,21 @@ bool ResourceRow::operator==(const ResourceRow& rhs) const { |
| always_revalidate == rhs.always_revalidate && score == rhs.score; |
| } |
| +// static |
| +void ResourceRow::FromProto(const ResourceData& proto, ResourceRow* row) { |
| + row->resource_url = GURL(proto.resource_url()); |
| + row->resource_type = |
| + static_cast<content::ResourceType>(proto.resource_type()); |
| + row->number_of_hits = proto.number_of_hits(); |
| + row->number_of_misses = proto.number_of_misses(); |
| + row->consecutive_misses = proto.consecutive_misses(); |
| + row->average_position = proto.average_position(); |
| + row->priority = static_cast<net::RequestPriority>(proto.priority()); |
| + row->has_validators = proto.has_validators(); |
| + row->always_revalidate = proto.always_revalidate(); |
| + row->UpdateScore(); |
| +} |
| + |
| void ResourceRow::ToProto(ResourceData* resource_data) const { |
| using chrome_browser_predictors::ResourceData_Priority; |
| using chrome_browser_predictors::ResourceData_ResourceType; |
| @@ -185,22 +253,8 @@ void ResourceRow::ToProto(ResourceData* resource_data) const { |
| } |
| // static |
| -void ResourceRow::FromProto(const ResourceData& proto, ResourceRow* row) { |
| - row->resource_url = GURL(proto.resource_url()); |
| - row->resource_type = |
| - static_cast<content::ResourceType>(proto.resource_type()); |
| - row->number_of_hits = proto.number_of_hits(); |
| - row->number_of_misses = proto.number_of_misses(); |
| - row->consecutive_misses = proto.consecutive_misses(); |
| - row->average_position = proto.average_position(); |
| - row->priority = static_cast<net::RequestPriority>(proto.priority()); |
| - row->has_validators = proto.has_validators(); |
| - row->always_revalidate = proto.always_revalidate(); |
| - row->UpdateScore(); |
| -} |
| - |
| -// static |
| -void ResourcePrefetchPredictorTables::SortResourceRows(ResourceRows* rows) { |
| +void ResourcePrefetchPredictorTables::SortResourceRows( |
| + std::vector<ResourceRow>* rows) { |
| std::sort(rows->begin(), rows->end(), |
| [](const ResourceRow& x, const ResourceRow& y) { |
| return x.score > y.score; |
| @@ -231,47 +285,181 @@ bool ResourcePrefetchPredictorTables::PrefetchData::operator==( |
| resources == rhs.resources; |
| } |
| +RedirectRow::RedirectRow() |
| + : number_of_hits(0), |
| + number_of_misses(0), |
| + consecutive_misses(0), |
| + score(0.0) {} |
| + |
| +RedirectRow::RedirectRow(const RedirectRow& other) |
| + : final_redirect(other.final_redirect), |
| + number_of_hits(other.number_of_hits), |
| + number_of_misses(other.number_of_misses), |
| + consecutive_misses(other.consecutive_misses), |
| + score(other.score) {} |
| + |
| +RedirectRow::RedirectRow( |
| + const std::string& i_final_redirect, |
| + size_t i_number_of_hits, |
| + size_t i_number_of_misses, |
| + size_t i_consecutive_misses) |
| + : final_redirect(i_final_redirect), |
| + number_of_hits(i_number_of_hits), |
| + number_of_misses(i_number_of_misses), |
| + consecutive_misses(i_consecutive_misses), |
| + score(0.0) {} |
| + |
| +void RedirectRow::UpdateScore() { |
| + // TODO(alexilin): invent some scoring |
| +} |
| + |
| +bool RedirectRow::operator==(const RedirectRow& rhs) const { |
| + return final_redirect == rhs.final_redirect && |
| + number_of_hits == rhs.number_of_hits && |
| + number_of_misses == rhs.number_of_misses && |
| + consecutive_misses == rhs.consecutive_misses; |
| +} |
| + |
| +// static |
| +void RedirectRow::FromProto(const RedirectStat& proto, RedirectRow* row) { |
| + row->final_redirect = proto.final_redirect(); |
| + row->number_of_hits = proto.number_of_hits(); |
| + row->number_of_misses = proto.number_of_misses(); |
| + row->consecutive_misses = proto.consecutive_misses(); |
| + row->UpdateScore(); |
| +} |
| + |
| +void RedirectRow::ToProto(RedirectStat* redirect_stat) const { |
| + redirect_stat->set_final_redirect(final_redirect); |
| + redirect_stat->set_number_of_hits(number_of_hits); |
| + redirect_stat->set_number_of_misses(number_of_misses); |
| + redirect_stat->set_consecutive_misses(consecutive_misses); |
| +} |
| + |
| +// static |
| +void ResourcePrefetchPredictorTables::SortRedirectRows( |
| + std::vector<RedirectRow>* rows) { |
| + std::sort(rows->begin(), rows->end(), |
| + [](const RedirectRow& x, const RedirectRow& y) { |
| + return x.score > y.score; |
| + }); |
| +} |
| + |
| +ResourcePrefetchPredictorTables::RedirectData::RedirectData( |
| + PrefetchKeyType i_key_type, |
| + const std::string& i_primary_key) |
| + : key_type(i_key_type), |
| + primary_key(i_primary_key) {} |
| + |
| +ResourcePrefetchPredictorTables::RedirectData::RedirectData( |
| + const RedirectData& other) |
| + : key_type(other.key_type), |
| + primary_key(other.primary_key), |
| + last_visit(other.last_visit), |
| + redirects(other.redirects) {} |
| + |
| +ResourcePrefetchPredictorTables::RedirectData::~RedirectData() { |
| +} |
| + |
| +bool ResourcePrefetchPredictorTables::RedirectData::operator==( |
| + const RedirectData& rhs) const { |
| + return key_type == rhs.key_type && primary_key == rhs.primary_key && |
| + redirects == rhs.redirects; |
| +} |
| + |
| void ResourcePrefetchPredictorTables::GetAllData( |
| PrefetchDataMap* url_data_map, |
| - PrefetchDataMap* host_data_map) { |
| + PrefetchDataMap* host_data_map, |
| + RedirectDataMap* url_redirect_data_map, |
| + RedirectDataMap* host_redirect_data_map) { |
| DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| if (CantAccessDatabase()) |
| return; |
| DCHECK(url_data_map); |
| DCHECK(host_data_map); |
| + DCHECK(url_redirect_data_map); |
| + DCHECK(host_redirect_data_map); |
| url_data_map->clear(); |
| host_data_map->clear(); |
| + url_redirect_data_map->clear(); |
| + host_redirect_data_map->clear(); |
| std::vector<std::string> urls_to_delete, hosts_to_delete; |
| + std::vector<std::string> url_redirects_to_delete, host_redirects_to_delete; |
| GetAllDataHelper(PREFETCH_KEY_TYPE_URL, url_data_map, &urls_to_delete); |
| GetAllDataHelper(PREFETCH_KEY_TYPE_HOST, host_data_map, &hosts_to_delete); |
| + GetAllDataHelper(PREFETCH_KEY_TYPE_URL, url_redirect_data_map, |
| + &url_redirects_to_delete); |
| + GetAllDataHelper(PREFETCH_KEY_TYPE_HOST, host_redirect_data_map, |
| + &host_redirects_to_delete); |
| if (!urls_to_delete.empty() || !hosts_to_delete.empty()) |
| - DeleteData(urls_to_delete, hosts_to_delete); |
| + DeleteResourceData(urls_to_delete, hosts_to_delete); |
| + |
| + if (!url_redirects_to_delete.empty() || !host_redirects_to_delete.empty()) |
| + DeleteRedirectData(url_redirects_to_delete, host_redirects_to_delete); |
| } |
| void ResourcePrefetchPredictorTables::UpdateData( |
| const PrefetchData& url_data, |
| - const PrefetchData& host_data) { |
| + const PrefetchData& host_data, |
| + const RedirectData& url_redirect_data, |
| + const RedirectData& host_redirect_data) { |
| DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| if (CantAccessDatabase()) |
| return; |
| DCHECK(!url_data.is_host() && host_data.is_host()); |
| - DCHECK(!url_data.primary_key.empty() || !host_data.primary_key.empty()); |
| + DCHECK(!url_redirect_data.is_host() && host_redirect_data.is_host()); |
| + DCHECK(!url_data.primary_key.empty() || |
| + !host_data.primary_key.empty() || |
| + !url_redirect_data.primary_key.empty() || |
| + !host_redirect_data.primary_key.empty()); |
| DB()->BeginTransaction(); |
| - bool success = (url_data.primary_key.empty() || UpdateDataHelper(url_data)) && |
| - (host_data.primary_key.empty() || UpdateDataHelper(host_data)); |
| + bool success = |
| + (url_data.primary_key.empty() || |
| + UpdateDataHelper(url_data)) && |
| + (host_data.primary_key.empty() || |
| + UpdateDataHelper(host_data)) && |
| + (url_redirect_data.primary_key.empty() || |
| + UpdateDataHelper(url_redirect_data)) && |
| + (host_redirect_data.primary_key.empty() || |
| + UpdateDataHelper(host_redirect_data)); |
| if (!success) |
| DB()->RollbackTransaction(); |
| DB()->CommitTransaction(); |
| } |
| -void ResourcePrefetchPredictorTables::DeleteData( |
| +void ResourcePrefetchPredictorTables::DeleteResourceData( |
| + const std::vector<std::string>& urls, |
| + const std::vector<std::string>& hosts) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| + if (CantAccessDatabase()) |
| + return; |
| + |
| + DCHECK(!urls.empty() || !hosts.empty()); |
| + |
| + if (!urls.empty()) |
| + DeleteResourceDataHelper(PREFETCH_KEY_TYPE_URL, urls); |
| + if (!hosts.empty()) |
| + DeleteResourceDataHelper(PREFETCH_KEY_TYPE_HOST, hosts); |
| +} |
| + |
| +void ResourcePrefetchPredictorTables::DeleteSingleResourceDataPoint( |
| + const std::string& key, |
| + PrefetchKeyType key_type) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| + if (CantAccessDatabase()) |
| + return; |
| + |
| + DeleteResourceDataHelper(key_type, std::vector<std::string>(1, key)); |
| +} |
| + |
| +void ResourcePrefetchPredictorTables::DeleteRedirectData( |
| const std::vector<std::string>& urls, |
| const std::vector<std::string>& hosts) { |
| DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| @@ -281,19 +469,19 @@ void ResourcePrefetchPredictorTables::DeleteData( |
| DCHECK(!urls.empty() || !hosts.empty()); |
| if (!urls.empty()) |
| - DeleteDataHelper(PREFETCH_KEY_TYPE_URL, urls); |
| + DeleteRedirectDataHelper(PREFETCH_KEY_TYPE_URL, urls); |
| if (!hosts.empty()) |
| - DeleteDataHelper(PREFETCH_KEY_TYPE_HOST, hosts); |
| + DeleteRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, hosts); |
| } |
| -void ResourcePrefetchPredictorTables::DeleteSingleDataPoint( |
| +void ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint( |
| const std::string& key, |
| PrefetchKeyType key_type) { |
| DCHECK_CURRENTLY_ON(BrowserThread::DB); |
| if (CantAccessDatabase()) |
| return; |
| - DeleteDataHelper(key_type, std::vector<std::string>(1, key)); |
| + DeleteRedirectDataHelper(key_type, std::vector<std::string>(1, key)); |
|
mattcary
2016/09/14 15:37:08
wouldn't std::vector<std::string>{key} be a little
alexilin
2016/09/14 18:59:55
Actually, we could use just {key}. Or do we need m
mattcary
2016/09/15 09:04:34
{key} works even better. I'm still a little weak o
|
| } |
| void ResourcePrefetchPredictorTables::DeleteAllData() { |
| @@ -302,8 +490,10 @@ void ResourcePrefetchPredictorTables::DeleteAllData() { |
| Statement deleter; |
| for (const char* table_name : |
| - {kUrlResourceTableName, kUrlMetadataTableName, kHostResourceTableName, |
| - kHostMetadataTableName}) { |
| + {kUrlResourceTableName, kUrlRedirectTableName, |
| + kUrlResourceMetadataTableName, kUrlRedirectMetadataTableName, |
| + kHostResourceTableName, kHostRedirectTableName, |
| + kHostResourceMetadataTableName, kHostRedirectMetadataTableName}) { |
| deleter.Assign(DB()->GetUniqueStatement( |
| base::StringPrintf("DELETE FROM %s", table_name).c_str())); |
| deleter.Run(); |
| @@ -346,8 +536,8 @@ void ResourcePrefetchPredictorTables::GetAllDataHelper( |
| // Read the metadata and keep track of entries that have metadata, but no |
| // resource entries, so they can be deleted. |
| - const char* metadata_table_name = is_host ? kHostMetadataTableName : |
| - kUrlMetadataTableName; |
| + const char* metadata_table_name = is_host ? kHostResourceMetadataTableName : |
| + kUrlResourceMetadataTableName; |
| Statement metadata_reader(DB()->GetUniqueStatement( |
| base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str())); |
| @@ -364,6 +554,52 @@ void ResourcePrefetchPredictorTables::GetAllDataHelper( |
| } |
| } |
| +void ResourcePrefetchPredictorTables::GetAllDataHelper( |
| + PrefetchKeyType key_type, |
|
mattcary
2016/09/14 15:37:09
I think I'd prefer to rename the function rather t
alexilin
2016/09/14 18:59:55
Done.
|
| + RedirectDataMap* redirect_map, |
| + std::vector<std::string>* to_delete) { |
| + bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; |
| + |
| + const char* redirect_table_name = is_host ? kHostRedirectTableName : |
| + kUrlRedirectTableName; |
| + Statement redirect_reader(DB()->GetUniqueStatement( |
| + base::StringPrintf("SELECT * FROM %s", redirect_table_name).c_str())); |
| + |
| + RedirectRow row; |
| + std::string primary_key; |
| + while (StepAndInitializeRedirectRow(&redirect_reader, &row, &primary_key)) { |
| + RedirectDataMap::iterator it = redirect_map->find(primary_key); |
| + if (it == redirect_map->end()) { |
| + it = redirect_map->insert(std::make_pair( |
| + primary_key, RedirectData(key_type, primary_key))).first; |
| + } |
| + it->second.redirects.push_back(row); |
| + } |
| + |
| + // Sort each of the redirect row vectors by score. |
| + for (auto& kv : *redirect_map) |
| + SortRedirectRows(&(kv.second.redirects)); |
| + |
| + // Read the metadata and keep track of entries that have metadata, but no |
| + // redirect entries, so they can be deleted |
| + const char* metadata_table_name = is_host ? kHostRedirectMetadataTableName : |
| + kUrlRedirectMetadataTableName; |
| + Statement metadata_reader(DB()->GetUniqueStatement( |
| + base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str())); |
| + |
| + while (metadata_reader.Step()) { |
| + std::string primary_key = metadata_reader.ColumnString(0); |
| + |
| + RedirectDataMap::iterator it = redirect_map->find(primary_key); |
| + if (it != redirect_map->end()) { |
| + int64_t last_visit = metadata_reader.ColumnInt64(1); |
| + it->second.last_visit = base::Time::FromInternalValue(last_visit); |
| + } else { |
| + to_delete->push_back(primary_key); |
| + } |
| + } |
| +} |
| + |
| bool ResourcePrefetchPredictorTables::UpdateDataHelper( |
| const PrefetchData& data) { |
| DCHECK(!data.primary_key.empty()); |
| @@ -381,8 +617,8 @@ bool ResourcePrefetchPredictorTables::UpdateDataHelper( |
| if (!deleter->Run()) |
| return false; |
| - deleter.reset(data.is_host() ? GetHostMetadataDeleteStatement() : |
| - GetUrlMetadataDeleteStatement()); |
| + deleter.reset(data.is_host() ? GetHostResourceMetadataDeleteStatement() : |
| + GetUrlResourceMetadataDeleteStatement()); |
| deleter->BindString(0, data.primary_key); |
| if (!deleter->Run()) |
| return false; |
| @@ -399,8 +635,52 @@ bool ResourcePrefetchPredictorTables::UpdateDataHelper( |
| } |
| std::unique_ptr<Statement> metadata_inserter( |
| - data.is_host() ? GetHostMetadataUpdateStatement() |
| - : GetUrlMetadataUpdateStatement()); |
| + data.is_host() ? GetHostResourceMetadataUpdateStatement() |
| + : GetUrlResourceMetadataUpdateStatement()); |
| + metadata_inserter->BindString(0, data.primary_key); |
| + metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue()); |
| + if (!metadata_inserter->Run()) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| +bool ResourcePrefetchPredictorTables::UpdateDataHelper( |
| + const RedirectData& data) { |
| + DCHECK(!data.primary_key.empty()); |
| + |
| + if (!StringsAreSmallerThanDBLimit(data)) { |
| + UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true); |
| + return false; |
| + } |
| + |
| + // Delete the older data from the table. |
| + std::unique_ptr<Statement> deleter(data.is_host() |
| + ? GetHostRedirectDeleteStatement() |
| + : GetUrlRedirectDeleteStatement()); |
| + deleter->BindString(0, data.primary_key); |
| + if (!deleter->Run()) |
| + return false; |
| + |
| + deleter.reset(data.is_host() ? GetHostRedirectMetadataDeleteStatement() : |
| + GetUrlRedirectMetadataDeleteStatement()); |
| + deleter->BindString(0, data.primary_key); |
| + if (!deleter->Run()) |
| + return false; |
| + |
| + // Add the new data to the table. |
| + for (const RedirectRow& row : data.redirects) { |
| + std::unique_ptr<Statement> row_inserter( |
| + data.is_host() ? GetHostRedirectUpdateStatement() |
| + : GetUrlRedirectUpdateStatement()); |
| + BindRedirectRowToStatement(row, data.primary_key, row_inserter.get()); |
| + if (!row_inserter->Run()) |
| + return false; |
| + } |
| + |
| + std::unique_ptr<Statement> metadata_inserter( |
| + data.is_host() ? GetHostRedirectMetadataUpdateStatement() |
| + : GetUrlRedirectMetadataUpdateStatement()); |
| metadata_inserter->BindString(0, data.primary_key); |
| metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue()); |
| if (!metadata_inserter->Run()) |
| @@ -409,7 +689,7 @@ bool ResourcePrefetchPredictorTables::UpdateDataHelper( |
| return true; |
| } |
| -void ResourcePrefetchPredictorTables::DeleteDataHelper( |
| +void ResourcePrefetchPredictorTables::DeleteResourceDataHelper( |
| PrefetchKeyType key_type, |
| const std::vector<std::string>& keys) { |
| bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; |
| @@ -421,8 +701,27 @@ void ResourcePrefetchPredictorTables::DeleteDataHelper( |
| deleter->BindString(0, key); |
| deleter->Run(); |
| - deleter.reset(is_host ? GetHostMetadataDeleteStatement() : |
| - GetUrlMetadataDeleteStatement()); |
| + deleter.reset(is_host ? GetHostResourceMetadataDeleteStatement() : |
| + GetUrlResourceMetadataDeleteStatement()); |
| + deleter->BindString(0, key); |
| + deleter->Run(); |
| + } |
| +} |
| + |
| +void ResourcePrefetchPredictorTables::DeleteRedirectDataHelper( |
| + PrefetchKeyType key_type, |
| + const std::vector<std::string>& keys) { |
| + bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; |
| + |
| + for (const std::string& key : keys) { |
| + std::unique_ptr<Statement> deleter(is_host |
| + ? GetHostRedirectDeleteStatement() |
| + : GetUrlRedirectDeleteStatement()); |
| + deleter->BindString(0, key); |
| + deleter->Run(); |
| + |
| + deleter.reset(is_host ? GetHostRedirectMetadataDeleteStatement() : |
| + GetUrlRedirectMetadataDeleteStatement()); |
| deleter->BindString(0, key); |
| deleter->Run(); |
| } |
| @@ -442,6 +741,19 @@ bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit( |
| } |
| // static |
| +bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit( |
| + const RedirectData& data) { |
| + if (data.primary_key.length() > kMaxStringLength) |
| + return false; |
| + |
| + for (const RedirectRow& row : data.redirects) { |
| + if (row.final_redirect.length() > kMaxStringLength) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +// static |
| bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( |
| sql::Connection* db) { |
| int version = GetDatabaseVersion(db); |
| @@ -452,7 +764,9 @@ bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( |
| if (incompatible_version) { |
| for (const char* table_name : |
| {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName, |
| - kUrlMetadataTableName, kHostMetadataTableName}) { |
| + kUrlRedirectTableName, kHostRedirectTableName, |
| + kUrlResourceMetadataTableName, kHostResourceMetadataTableName, |
| + kUrlRedirectMetadataTableName, kHostRedirectMetadataTableName}) { |
| success = |
| success && |
| db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name) |
| @@ -515,17 +829,33 @@ void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() { |
| db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, |
| kUrlResourceTableName) |
| .c_str())) && |
| - (db->DoesTableExist(kUrlMetadataTableName) || |
| + (db->DoesTableExist(kUrlRedirectTableName) || |
| + db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate, |
| + kUrlRedirectTableName) |
| + .c_str())) && |
| + (db->DoesTableExist(kUrlResourceMetadataTableName) || |
| + db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, |
| + kUrlResourceMetadataTableName) |
| + .c_str())) && |
| + (db->DoesTableExist(kUrlRedirectMetadataTableName) || |
| db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, |
| - kUrlMetadataTableName) |
| + kUrlRedirectMetadataTableName) |
| .c_str())) && |
| (db->DoesTableExist(kHostResourceTableName) || |
| db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, |
| kHostResourceTableName) |
| .c_str())) && |
| - (db->DoesTableExist(kHostMetadataTableName) || |
| + (db->DoesTableExist(kHostRedirectTableName) || |
| + db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate, |
| + kHostRedirectTableName) |
| + .c_str())) && |
| + (db->DoesTableExist(kHostResourceMetadataTableName) || |
| + db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, |
| + kHostResourceMetadataTableName) |
| + .c_str())); |
| + (db->DoesTableExist(kHostRedirectMetadataTableName) || |
| db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, |
| - kHostMetadataTableName) |
| + kHostRedirectMetadataTableName) |
| .c_str())); |
| if (success) |
| @@ -555,6 +885,20 @@ void ResourcePrefetchPredictorTables::LogDatabaseStats() { |
| if (statement.Step()) |
| UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount", |
| statement.ColumnInt(0)); |
| + |
| + statement.Assign(DB()->GetUniqueStatement( |
| + base::StringPrintf("SELECT count(*) FROM %s", |
| + kUrlRedirectTableName).c_str())); |
| + if (statement.Step()) |
| + UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlRedirectTableRowCount", |
| + statement.ColumnInt(0)); |
| + |
| + statement.Assign(DB()->GetUniqueStatement( |
| + base::StringPrintf("SELECT count(*) FROM %s", |
| + kHostRedirectTableName).c_str())); |
| + if (statement.Step()) |
| + UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostRedirectTableRowCount", |
| + statement.ColumnInt(0)); |
| } |
| Statement* |
| @@ -574,18 +918,52 @@ Statement* |
| } |
| Statement* |
| - ResourcePrefetchPredictorTables::GetUrlMetadataDeleteStatement() { |
| + ResourcePrefetchPredictorTables::GetUrlResourceMetadataDeleteStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, |
| + base::StringPrintf(kDeleteStatementTemplate, |
| + kUrlResourceMetadataTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetUrlResourceMetadataUpdateStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, |
| + kUrlResourceMetadataTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetUrlRedirectDeleteStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, |
| + base::StringPrintf(kDeleteStatementTemplate, kUrlRedirectTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetUrlRedirectUpdateStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, base::StringPrintf(kInsertRedirectTableStatementTemplate, |
| + kUrlRedirectTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetUrlRedirectMetadataDeleteStatement() { |
| return new Statement(DB()->GetCachedStatement( |
| SQL_FROM_HERE, |
| - base::StringPrintf(kDeleteStatementTemplate, kUrlMetadataTableName) |
| + base::StringPrintf(kDeleteStatementTemplate, |
| + kUrlRedirectMetadataTableName) |
| .c_str())); |
| } |
| Statement* |
| - ResourcePrefetchPredictorTables::GetUrlMetadataUpdateStatement() { |
| + ResourcePrefetchPredictorTables::GetUrlRedirectMetadataUpdateStatement() { |
| return new Statement(DB()->GetCachedStatement( |
| SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, |
| - kUrlMetadataTableName) |
| + kUrlRedirectMetadataTableName) |
| .c_str())); |
| } |
| @@ -606,17 +984,50 @@ Statement* |
| } |
| Statement* |
| - ResourcePrefetchPredictorTables::GetHostMetadataDeleteStatement() { |
| + ResourcePrefetchPredictorTables::GetHostResourceMetadataDeleteStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, base::StringPrintf(kDeleteStatementTemplate, |
| + kHostResourceMetadataTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetHostResourceMetadataUpdateStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, |
| + kHostResourceMetadataTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetHostRedirectDeleteStatement() { |
| return new Statement(DB()->GetCachedStatement( |
| SQL_FROM_HERE, |
| - base::StringPrintf(kDeleteStatementTemplate, kHostMetadataTableName) |
| + base::StringPrintf(kDeleteStatementTemplate, kHostRedirectTableName) |
| .c_str())); |
| } |
| -Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() { |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetHostRedirectUpdateStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, base::StringPrintf(kInsertRedirectTableStatementTemplate, |
| + kHostRedirectTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetHostRedirectMetadataDeleteStatement() { |
| + return new Statement(DB()->GetCachedStatement( |
| + SQL_FROM_HERE, base::StringPrintf(kDeleteStatementTemplate, |
| + kHostRedirectMetadataTableName) |
| + .c_str())); |
| +} |
| + |
| +Statement* |
| + ResourcePrefetchPredictorTables::GetHostRedirectMetadataUpdateStatement() { |
| return new Statement(DB()->GetCachedStatement( |
| SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, |
| - kHostMetadataTableName) |
| + kHostRedirectMetadataTableName) |
| .c_str())); |
| } |