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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 row.ToProto(&proto); | 61 row.ToProto(&proto); |
62 int size = proto.ByteSize(); | 62 int size = proto.ByteSize(); |
63 std::vector<char> proto_buffer(size); | 63 std::vector<char> proto_buffer(size); |
64 proto.SerializeToArray(&proto_buffer[0], size); | 64 proto.SerializeToArray(&proto_buffer[0], size); |
65 | 65 |
66 statement->BindString(0, primary_key); | 66 statement->BindString(0, primary_key); |
67 statement->BindString(1, row.resource_url.spec()); | 67 statement->BindString(1, row.resource_url.spec()); |
68 statement->BindBlob(2, &proto_buffer[0], size); | 68 statement->BindBlob(2, &proto_buffer[0], size); |
69 } | 69 } |
70 | 70 |
71 bool StepAndInitializeResourceRow(Statement* statement, ResourceRow* row) { | 71 bool StepAndInitializeResourceRow(Statement* statement, |
| 72 ResourceRow* row, |
| 73 std::string* primary_key) { |
72 if (!statement->Step()) | 74 if (!statement->Step()) |
73 return false; | 75 return false; |
74 | 76 |
| 77 *primary_key = statement->ColumnString(0); |
| 78 |
75 int size = statement->ColumnByteLength(2); | 79 int size = statement->ColumnByteLength(2); |
76 const void* data = statement->ColumnBlob(2); | 80 const void* data = statement->ColumnBlob(2); |
77 DCHECK(data); | 81 DCHECK(data); |
78 chrome_browser_predictors::ResourceData proto; | 82 chrome_browser_predictors::ResourceData proto; |
79 proto.ParseFromArray(data, size); | 83 proto.ParseFromArray(data, size); |
80 ResourceRow::FromProto(proto, row); | 84 ResourceRow::FromProto(proto, row); |
81 | 85 |
82 row->primary_key = statement->ColumnString(0); | 86 GURL resource_url(statement->ColumnString(1)); |
83 row->resource_url = GURL(statement->ColumnString(1)); | 87 DCHECK(resource_url == row->resource_url); |
| 88 |
84 return true; | 89 return true; |
85 } | 90 } |
86 | 91 |
87 } // namespace | 92 } // namespace |
88 | 93 |
89 namespace predictors { | 94 namespace predictors { |
90 | 95 |
91 // static | |
92 const size_t ResourcePrefetchPredictorTables::kMaxStringLength = 1024; | |
93 | |
94 ResourceRow::ResourceRow() | 96 ResourceRow::ResourceRow() |
95 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), | 97 : resource_type(content::RESOURCE_TYPE_LAST_TYPE), |
96 number_of_hits(0), | 98 number_of_hits(0), |
97 number_of_misses(0), | 99 number_of_misses(0), |
98 consecutive_misses(0), | 100 consecutive_misses(0), |
99 average_position(0.0), | 101 average_position(0.0), |
100 priority(net::IDLE), | 102 priority(net::IDLE), |
101 has_validators(false), | 103 has_validators(false), |
102 always_revalidate(false), | 104 always_revalidate(false), |
103 score(0.0) {} | 105 score(0.0) {} |
104 | 106 |
105 ResourceRow::ResourceRow(const ResourceRow& other) | 107 ResourceRow::ResourceRow(const ResourceRow& other) |
106 : primary_key(other.primary_key), | 108 : resource_url(other.resource_url), |
107 resource_url(other.resource_url), | |
108 resource_type(other.resource_type), | 109 resource_type(other.resource_type), |
109 number_of_hits(other.number_of_hits), | 110 number_of_hits(other.number_of_hits), |
110 number_of_misses(other.number_of_misses), | 111 number_of_misses(other.number_of_misses), |
111 consecutive_misses(other.consecutive_misses), | 112 consecutive_misses(other.consecutive_misses), |
112 average_position(other.average_position), | 113 average_position(other.average_position), |
113 priority(other.priority), | 114 priority(other.priority), |
114 has_validators(other.has_validators), | 115 has_validators(other.has_validators), |
115 always_revalidate(other.always_revalidate), | 116 always_revalidate(other.always_revalidate), |
116 score(other.score) {} | 117 score(other.score) {} |
117 | 118 |
118 ResourceRow::ResourceRow(const std::string& i_primary_key, | 119 ResourceRow::ResourceRow(const std::string& i_resource_url, |
119 const std::string& i_resource_url, | |
120 content::ResourceType i_resource_type, | 120 content::ResourceType i_resource_type, |
121 int i_number_of_hits, | 121 int i_number_of_hits, |
122 int i_number_of_misses, | 122 int i_number_of_misses, |
123 int i_consecutive_misses, | 123 int i_consecutive_misses, |
124 double i_average_position, | 124 double i_average_position, |
125 net::RequestPriority i_priority, | 125 net::RequestPriority i_priority, |
126 bool i_has_validators, | 126 bool i_has_validators, |
127 bool i_always_revalidate) | 127 bool i_always_revalidate) |
128 : primary_key(i_primary_key), | 128 : resource_url(i_resource_url), |
129 resource_url(i_resource_url), | |
130 resource_type(i_resource_type), | 129 resource_type(i_resource_type), |
131 number_of_hits(i_number_of_hits), | 130 number_of_hits(i_number_of_hits), |
132 number_of_misses(i_number_of_misses), | 131 number_of_misses(i_number_of_misses), |
133 consecutive_misses(i_consecutive_misses), | 132 consecutive_misses(i_consecutive_misses), |
134 average_position(i_average_position), | 133 average_position(i_average_position), |
135 priority(i_priority), | 134 priority(i_priority), |
136 has_validators(i_has_validators), | 135 has_validators(i_has_validators), |
137 always_revalidate(i_always_revalidate) { | 136 always_revalidate(i_always_revalidate) { |
138 UpdateScore(); | 137 UpdateScore(); |
139 } | 138 } |
(...skipping 12 matching lines...) Expand all Loading... |
152 | 151 |
153 case content::RESOURCE_TYPE_IMAGE: | 152 case content::RESOURCE_TYPE_IMAGE: |
154 default: | 153 default: |
155 score = kMaxResourcesPerType - average_position; | 154 score = kMaxResourcesPerType - average_position; |
156 break; | 155 break; |
157 } | 156 } |
158 // TODO(lizeb): Take priority into account. | 157 // TODO(lizeb): Take priority into account. |
159 } | 158 } |
160 | 159 |
161 bool ResourceRow::operator==(const ResourceRow& rhs) const { | 160 bool ResourceRow::operator==(const ResourceRow& rhs) const { |
162 return primary_key == rhs.primary_key && resource_url == rhs.resource_url && | 161 return resource_url == rhs.resource_url && |
163 resource_type == rhs.resource_type && | 162 resource_type == rhs.resource_type && |
164 number_of_hits == rhs.number_of_hits && | 163 number_of_hits == rhs.number_of_hits && |
165 number_of_misses == rhs.number_of_misses && | 164 number_of_misses == rhs.number_of_misses && |
166 consecutive_misses == rhs.consecutive_misses && | 165 consecutive_misses == rhs.consecutive_misses && |
167 average_position == rhs.average_position && priority == rhs.priority && | 166 average_position == rhs.average_position && priority == rhs.priority && |
168 has_validators == rhs.has_validators && | 167 has_validators == rhs.has_validators && |
169 always_revalidate == rhs.always_revalidate && score == rhs.score; | 168 always_revalidate == rhs.always_revalidate && score == rhs.score; |
170 } | 169 } |
171 | 170 |
172 void ResourceRow::ToProto(ResourceData* resource_data) const { | 171 void ResourceRow::ToProto(ResourceData* resource_data) const { |
173 using chrome_browser_predictors::ResourceData_Priority; | 172 using chrome_browser_predictors::ResourceData_Priority; |
174 using chrome_browser_predictors::ResourceData_ResourceType; | 173 using chrome_browser_predictors::ResourceData_ResourceType; |
175 | 174 |
176 resource_data->set_primary_key(primary_key); | |
177 resource_data->set_resource_url(resource_url.spec()); | 175 resource_data->set_resource_url(resource_url.spec()); |
178 resource_data->set_resource_type( | 176 resource_data->set_resource_type( |
179 static_cast<ResourceData_ResourceType>(resource_type)); | 177 static_cast<ResourceData_ResourceType>(resource_type)); |
180 resource_data->set_number_of_hits(number_of_hits); | 178 resource_data->set_number_of_hits(number_of_hits); |
181 resource_data->set_number_of_misses(number_of_misses); | 179 resource_data->set_number_of_misses(number_of_misses); |
182 resource_data->set_consecutive_misses(consecutive_misses); | 180 resource_data->set_consecutive_misses(consecutive_misses); |
183 resource_data->set_average_position(average_position); | 181 resource_data->set_average_position(average_position); |
184 resource_data->set_priority(static_cast<ResourceData_Priority>(priority)); | 182 resource_data->set_priority(static_cast<ResourceData_Priority>(priority)); |
185 resource_data->set_has_validators(has_validators); | 183 resource_data->set_has_validators(has_validators); |
186 resource_data->set_always_revalidate(always_revalidate); | 184 resource_data->set_always_revalidate(always_revalidate); |
187 } | 185 } |
188 | 186 |
189 // static | 187 // static |
190 void ResourceRow::FromProto(const ResourceData& proto, ResourceRow* row) { | 188 void ResourceRow::FromProto(const ResourceData& proto, ResourceRow* row) { |
191 DCHECK(proto.has_primary_key()); | |
192 row->primary_key = proto.primary_key(); | |
193 row->resource_url = GURL(proto.resource_url()); | 189 row->resource_url = GURL(proto.resource_url()); |
194 row->resource_type = | 190 row->resource_type = |
195 static_cast<content::ResourceType>(proto.resource_type()); | 191 static_cast<content::ResourceType>(proto.resource_type()); |
196 row->number_of_hits = proto.number_of_hits(); | 192 row->number_of_hits = proto.number_of_hits(); |
197 row->number_of_misses = proto.number_of_misses(); | 193 row->number_of_misses = proto.number_of_misses(); |
198 row->consecutive_misses = proto.consecutive_misses(); | 194 row->consecutive_misses = proto.consecutive_misses(); |
199 row->average_position = proto.average_position(); | 195 row->average_position = proto.average_position(); |
200 row->priority = static_cast<net::RequestPriority>(proto.priority()); | 196 row->priority = static_cast<net::RequestPriority>(proto.priority()); |
201 row->has_validators = proto.has_validators(); | 197 row->has_validators = proto.has_validators(); |
202 row->always_revalidate = proto.always_revalidate(); | 198 row->always_revalidate = proto.always_revalidate(); |
| 199 row->UpdateScore(); |
203 } | 200 } |
204 | 201 |
205 // static | 202 // static |
206 void ResourcePrefetchPredictorTables::SortResourceRows(ResourceRows* rows) { | 203 void ResourcePrefetchPredictorTables::SortResourceRows(ResourceRows* rows) { |
207 std::sort(rows->begin(), rows->end(), | 204 std::sort(rows->begin(), rows->end(), |
208 [](const ResourceRow& x, const ResourceRow& y) { | 205 [](const ResourceRow& x, const ResourceRow& y) { |
209 return x.score > y.score; | 206 return x.score > y.score; |
210 }); | 207 }); |
211 } | 208 } |
212 | 209 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 if (CantAccessDatabase()) | 293 if (CantAccessDatabase()) |
297 return; | 294 return; |
298 | 295 |
299 DeleteDataHelper(key_type, std::vector<std::string>(1, key)); | 296 DeleteDataHelper(key_type, std::vector<std::string>(1, key)); |
300 } | 297 } |
301 | 298 |
302 void ResourcePrefetchPredictorTables::DeleteAllData() { | 299 void ResourcePrefetchPredictorTables::DeleteAllData() { |
303 if (CantAccessDatabase()) | 300 if (CantAccessDatabase()) |
304 return; | 301 return; |
305 | 302 |
306 Statement deleter(DB()->GetUniqueStatement( | 303 Statement deleter; |
307 base::StringPrintf("DELETE FROM %s", kUrlResourceTableName).c_str())); | 304 for (const char* table_name : |
308 deleter.Run(); | 305 {kUrlResourceTableName, kUrlMetadataTableName, kHostResourceTableName, |
309 deleter.Assign(DB()->GetUniqueStatement( | 306 kHostMetadataTableName}) { |
310 base::StringPrintf("DELETE FROM %s", kUrlMetadataTableName).c_str())); | 307 deleter.Assign(DB()->GetUniqueStatement( |
311 deleter.Run(); | 308 base::StringPrintf("DELETE FROM %s", table_name).c_str())); |
312 deleter.Assign(DB()->GetUniqueStatement( | 309 deleter.Run(); |
313 base::StringPrintf("DELETE FROM %s", kHostResourceTableName).c_str())); | 310 } |
314 deleter.Run(); | |
315 deleter.Assign(DB()->GetUniqueStatement( | |
316 base::StringPrintf("DELETE FROM %s", kHostMetadataTableName).c_str())); | |
317 deleter.Run(); | |
318 } | 311 } |
319 | 312 |
320 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() | 313 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() |
321 : PredictorTableBase() { | 314 : PredictorTableBase() { |
322 } | 315 } |
323 | 316 |
324 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() { | 317 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() { |
325 } | 318 } |
326 | 319 |
327 void ResourcePrefetchPredictorTables::GetAllDataHelper( | 320 void ResourcePrefetchPredictorTables::GetAllDataHelper( |
328 PrefetchKeyType key_type, | 321 PrefetchKeyType key_type, |
329 PrefetchDataMap* data_map, | 322 PrefetchDataMap* data_map, |
330 std::vector<std::string>* to_delete) { | 323 std::vector<std::string>* to_delete) { |
331 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; | 324 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; |
332 | 325 |
333 // Read the resources table and organize it per primary key. | 326 // Read the resources table and organize it per primary key. |
334 const char* resource_table_name = is_host ? kHostResourceTableName : | 327 const char* resource_table_name = is_host ? kHostResourceTableName : |
335 kUrlResourceTableName; | 328 kUrlResourceTableName; |
336 Statement resource_reader(DB()->GetUniqueStatement( | 329 Statement resource_reader(DB()->GetUniqueStatement( |
337 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str())); | 330 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str())); |
338 | 331 |
339 ResourceRow row; | 332 ResourceRow row; |
340 while (StepAndInitializeResourceRow(&resource_reader, &row)) { | 333 std::string primary_key; |
341 row.UpdateScore(); | 334 while (StepAndInitializeResourceRow(&resource_reader, &row, &primary_key)) { |
342 std::string primary_key = row.primary_key; | |
343 // Don't need to store primary key since the data is grouped by primary key. | |
344 row.primary_key.clear(); | |
345 | |
346 PrefetchDataMap::iterator it = data_map->find(primary_key); | 335 PrefetchDataMap::iterator it = data_map->find(primary_key); |
347 if (it == data_map->end()) { | 336 if (it == data_map->end()) { |
348 it = data_map->insert(std::make_pair( | 337 it = data_map->insert(std::make_pair( |
349 primary_key, PrefetchData(key_type, primary_key))).first; | 338 primary_key, PrefetchData(key_type, primary_key))).first; |
350 } | 339 } |
351 it->second.resources.push_back(row); | 340 it->second.resources.push_back(row); |
352 } | 341 } |
353 | 342 |
354 // Sort each of the resource row vectors by score. | 343 // Sort each of the resource row vectors by score. |
355 for (auto& kv : *data_map) | 344 for (auto& kv : *data_map) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 if (!deleter->Run()) | 381 if (!deleter->Run()) |
393 return false; | 382 return false; |
394 | 383 |
395 deleter.reset(data.is_host() ? GetHostMetadataDeleteStatement() : | 384 deleter.reset(data.is_host() ? GetHostMetadataDeleteStatement() : |
396 GetUrlMetadataDeleteStatement()); | 385 GetUrlMetadataDeleteStatement()); |
397 deleter->BindString(0, data.primary_key); | 386 deleter->BindString(0, data.primary_key); |
398 if (!deleter->Run()) | 387 if (!deleter->Run()) |
399 return false; | 388 return false; |
400 | 389 |
401 // Add the new data to the tables. | 390 // Add the new data to the tables. |
402 const ResourceRows& resources = data.resources; | 391 for (const ResourceRow& resource : data.resources) { |
403 for (const ResourceRow& resource : resources) { | |
404 std::unique_ptr<Statement> resource_inserter( | 392 std::unique_ptr<Statement> resource_inserter( |
405 data.is_host() ? GetHostResourceUpdateStatement() | 393 data.is_host() ? GetHostResourceUpdateStatement() |
406 : GetUrlResourceUpdateStatement()); | 394 : GetUrlResourceUpdateStatement()); |
407 BindResourceRowToStatement(resource, data.primary_key, | 395 BindResourceRowToStatement(resource, data.primary_key, |
408 resource_inserter.get()); | 396 resource_inserter.get()); |
409 if (!resource_inserter->Run()) | 397 if (!resource_inserter->Run()) |
410 return false; | 398 return false; |
411 } | 399 } |
412 | 400 |
413 std::unique_ptr<Statement> metadata_inserter( | 401 std::unique_ptr<Statement> metadata_inserter( |
414 data.is_host() ? GetHostMetadataUpdateStatement() | 402 data.is_host() ? GetHostMetadataUpdateStatement() |
415 : GetUrlMetadataUpdateStatement()); | 403 : GetUrlMetadataUpdateStatement()); |
416 metadata_inserter->BindString(0, data.primary_key); | 404 metadata_inserter->BindString(0, data.primary_key); |
417 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue()); | 405 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue()); |
418 if (!metadata_inserter->Run()) | 406 if (!metadata_inserter->Run()) |
419 return false; | 407 return false; |
420 | 408 |
421 return true; | 409 return true; |
422 } | 410 } |
423 | 411 |
424 void ResourcePrefetchPredictorTables::DeleteDataHelper( | 412 void ResourcePrefetchPredictorTables::DeleteDataHelper( |
425 PrefetchKeyType key_type, | 413 PrefetchKeyType key_type, |
426 const std::vector<std::string>& keys) { | 414 const std::vector<std::string>& keys) { |
427 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; | 415 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; |
428 | 416 |
429 for (std::vector<std::string>::const_iterator it = keys.begin(); | 417 for (const std::string& key : keys) { |
430 it != keys.end(); ++it) { | |
431 std::unique_ptr<Statement> deleter(is_host | 418 std::unique_ptr<Statement> deleter(is_host |
432 ? GetHostResourceDeleteStatement() | 419 ? GetHostResourceDeleteStatement() |
433 : GetUrlResourceDeleteStatement()); | 420 : GetUrlResourceDeleteStatement()); |
434 deleter->BindString(0, *it); | 421 deleter->BindString(0, key); |
435 deleter->Run(); | 422 deleter->Run(); |
436 | 423 |
437 deleter.reset(is_host ? GetHostMetadataDeleteStatement() : | 424 deleter.reset(is_host ? GetHostMetadataDeleteStatement() : |
438 GetUrlMetadataDeleteStatement()); | 425 GetUrlMetadataDeleteStatement()); |
439 deleter->BindString(0, *it); | 426 deleter->BindString(0, key); |
440 deleter->Run(); | 427 deleter->Run(); |
441 } | 428 } |
442 } | 429 } |
443 | 430 |
| 431 // static |
444 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit( | 432 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit( |
445 const PrefetchData& data) const { | 433 const PrefetchData& data) { |
446 if (data.primary_key.length() > kMaxStringLength) | 434 if (data.primary_key.length() > kMaxStringLength) |
447 return false; | 435 return false; |
448 | 436 |
449 for (ResourceRows::const_iterator it = data.resources.begin(); | 437 for (const ResourceRow& row : data.resources) { |
450 it != data.resources.end(); ++it) { | 438 if (row.resource_url.spec().length() > kMaxStringLength) |
451 if (it->resource_url.spec().length() > kMaxStringLength) | |
452 return false; | 439 return false; |
453 } | 440 } |
454 return true; | 441 return true; |
455 } | 442 } |
456 | 443 |
457 // static | 444 // static |
458 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( | 445 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( |
459 sql::Connection* db) { | 446 sql::Connection* db) { |
460 int version = GetDatabaseVersion(db); | 447 int version = GetDatabaseVersion(db); |
461 bool success = true; | 448 bool success = true; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 } | 614 } |
628 | 615 |
629 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() { | 616 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() { |
630 return new Statement(DB()->GetCachedStatement( | 617 return new Statement(DB()->GetCachedStatement( |
631 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, | 618 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, |
632 kHostMetadataTableName) | 619 kHostMetadataTableName) |
633 .c_str())); | 620 .c_str())); |
634 } | 621 } |
635 | 622 |
636 } // namespace predictors | 623 } // namespace predictors |
OLD | NEW |