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

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

Issue 2388783002: predictors: Refactor resource_prefetch_predictor_tables. (Closed)
Patch Set: Fix nits. Created 4 years, 2 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 ResourceData = predictors::ResourceData; 26 using PrefetchData = predictors::PrefetchData;
27 using RedirectData = predictors::RedirectData; 27 using RedirectData = predictors::RedirectData;
28 using ::google::protobuf::MessageLite;
28 29
29 const char kMetadataTableName[] = "resource_prefetch_predictor_metadata"; 30 const char kMetadataTableName[] = "resource_prefetch_predictor_metadata";
30 const char kUrlResourceTableName[] = "resource_prefetch_predictor_url"; 31 const char kUrlResourceTableName[] = "resource_prefetch_predictor_url";
31 const char kUrlMetadataTableName[] = "resource_prefetch_predictor_url_metadata";
32 const char kUrlRedirectTableName[] = "resource_prefetch_predictor_url_redirect"; 32 const char kUrlRedirectTableName[] = "resource_prefetch_predictor_url_redirect";
33 const char kHostResourceTableName[] = "resource_prefetch_predictor_host"; 33 const char kHostResourceTableName[] = "resource_prefetch_predictor_host";
34 const char kHostMetadataTableName[] =
35 "resource_prefetch_predictor_host_metadata";
36 const char kHostRedirectTableName[] = 34 const char kHostRedirectTableName[] =
37 "resource_prefetch_predictor_host_redirect"; 35 "resource_prefetch_predictor_host_redirect";
38 36
39 const char kCreateGlobalMetadataStatementTemplate[] = 37 const char kCreateGlobalMetadataStatementTemplate[] =
40 "CREATE TABLE %s ( " 38 "CREATE TABLE %s ( "
41 "key TEXT, value INTEGER, " 39 "key TEXT, value INTEGER, "
42 "PRIMARY KEY (key))"; 40 "PRIMARY KEY (key))";
43 const char kCreateResourceTableStatementTemplate[] = 41 const char kCreateProtoTableStatementTemplate[] =
44 "CREATE TABLE %s ( " 42 "CREATE TABLE %s ( "
45 "main_page_url TEXT, " 43 "key TEXT, "
46 "resource_url TEXT, "
47 "proto BLOB, " 44 "proto BLOB, "
48 "PRIMARY KEY(main_page_url, resource_url))"; 45 "PRIMARY KEY(key))";
49 const char kCreateMetadataTableStatementTemplate[] = 46 const char kInsertProtoTableStatementTemplate[] =
50 "CREATE TABLE %s ( " 47 "INSERT INTO %s (key, proto) VALUES (?,?)";
51 "main_page_url TEXT, " 48 const char kDeleteProtoTableStatementTemplate[] = "DELETE FROM %s WHERE key=?";
52 "last_visit_time INTEGER, "
53 "PRIMARY KEY(main_page_url))";
54 const char kCreateRedirectTableStatementTemplate[] =
55 "CREATE TABLE %s ( "
56 "main_page_url TEXT, "
57 "proto BLOB, "
58 "PRIMARY KEY(main_page_url))";
59 49
60 const char kInsertResourceTableStatementTemplate[] = 50 void BindProtoDataToStatement(const std::string& key,
61 "INSERT INTO %s (main_page_url, resource_url, proto) VALUES (?,?,?)"; 51 const MessageLite& data,
62 const char kInsertRedirectTableStatementTemplate[] = 52 Statement* statement) {
63 "INSERT INTO %s (main_page_url, proto) VALUES (?,?)";
64 const char kInsertMetadataTableStatementTemplate[] =
65 "INSERT INTO %s (main_page_url, last_visit_time) VALUES (?,?)";
66 const char kDeleteStatementTemplate[] = "DELETE FROM %s WHERE main_page_url=?";
67
68 void BindResourceDataToStatement(const ResourceData& data,
69 const std::string& primary_key,
70 Statement* statement) {
71 int size = data.ByteSize(); 53 int size = data.ByteSize();
72 DCHECK_GT(size, 0); 54 DCHECK_GT(size, 0);
73 std::vector<char> proto_buffer(size); 55 std::vector<char> proto_buffer(size);
74 data.SerializeToArray(&proto_buffer[0], size); 56 data.SerializeToArray(&proto_buffer[0], size);
75 57
76 statement->BindString(0, primary_key); 58 statement->BindString(0, key);
77 statement->BindString(1, data.resource_url());
78 statement->BindBlob(2, &proto_buffer[0], size);
79 }
80
81 void BindRedirectDataToStatement(const RedirectData& data,
82 Statement* statement) {
83 int size = data.ByteSize();
84 DCHECK_GT(size, 0);
85 std::vector<char> proto_buffer(size);
86 data.SerializeToArray(&proto_buffer[0], size);
87
88 statement->BindString(0, data.primary_key());
89 statement->BindBlob(1, &proto_buffer[0], size); 59 statement->BindBlob(1, &proto_buffer[0], size);
90 } 60 }
91 61
92 bool StepAndInitializeResourceData(Statement* statement, 62 bool StepAndInitializeProtoData(Statement* statement,
93 ResourceData* data, 63 std::string* key,
94 std::string* primary_key) { 64 MessageLite* data) {
95 if (!statement->Step()) 65 if (!statement->Step())
96 return false; 66 return false;
97 67
98 *primary_key = statement->ColumnString(0); 68 *key = statement->ColumnString(0);
99 int size = statement->ColumnByteLength(2);
100 const void* blob = statement->ColumnBlob(2);
101 DCHECK(blob);
102 data->ParseFromArray(blob, size);
103
104 std::string resource_url = statement->ColumnString(1);
105 DCHECK(resource_url == data->resource_url());
106
107 return true;
108 }
109
110 bool StepAndInitializeRedirectData(Statement* statement,
111 RedirectData* data,
112 std::string* primary_key) {
113 if (!statement->Step())
114 return false;
115
116 *primary_key = statement->ColumnString(0);
117 69
118 int size = statement->ColumnByteLength(1); 70 int size = statement->ColumnByteLength(1);
119 const void* blob = statement->ColumnBlob(1); 71 const void* blob = statement->ColumnBlob(1);
120 DCHECK(blob); 72 DCHECK(blob);
121 data->ParseFromArray(blob, size); 73 data->ParseFromArray(blob, size);
122 74
123 DCHECK(data->primary_key() == *primary_key);
124
125 return true; 75 return true;
126 } 76 }
127 77
128 } // namespace 78 } // namespace
129 79
130 namespace predictors { 80 namespace predictors {
131 81
132 // static 82 // static
133 void ResourcePrefetchPredictorTables::SortResources( 83 void ResourcePrefetchPredictorTables::TrimResources(
134 std::vector<ResourceData>* resources) { 84 PrefetchData* data,
135 std::sort(resources->begin(), resources->end(), 85 size_t max_consecutive_misses) {
86 auto new_end = std::remove_if(
87 data->mutable_resources()->begin(), data->mutable_resources()->end(),
88 [max_consecutive_misses](const ResourceData& x) {
89 return x.consecutive_misses() >= max_consecutive_misses;
90 });
91 data->mutable_resources()->erase(new_end, data->mutable_resources()->end());
92 }
93
94 // static
95 void ResourcePrefetchPredictorTables::SortResources(PrefetchData* data) {
96 std::sort(data->mutable_resources()->begin(),
97 data->mutable_resources()->end(),
136 [](const ResourceData& x, const ResourceData& y) { 98 [](const ResourceData& x, const ResourceData& y) {
137 return ComputeResourceScore(x) > ComputeResourceScore(y); 99 return ComputeResourceScore(x) > ComputeResourceScore(y);
138 }); 100 });
139 } 101 }
140 102
141 // static 103 // static
142 void ResourcePrefetchPredictorTables::SortRedirects( 104 void ResourcePrefetchPredictorTables::TrimRedirects(
143 std::vector<RedirectStat>* redirects) { 105 RedirectData* data,
144 std::sort(redirects->begin(), redirects->end(), 106 size_t max_consecutive_misses) {
107 auto new_end =
108 std::remove_if(data->mutable_redirect_endpoints()->begin(),
109 data->mutable_redirect_endpoints()->end(),
110 [max_consecutive_misses](const RedirectStat& x) {
111 return x.consecutive_misses() >= max_consecutive_misses;
112 });
113 data->mutable_redirect_endpoints()->erase(
114 new_end, data->mutable_redirect_endpoints()->end());
115 }
116
117 // static
118 void ResourcePrefetchPredictorTables::SortRedirects(RedirectData* data) {
119 std::sort(data->mutable_redirect_endpoints()->begin(),
120 data->mutable_redirect_endpoints()->end(),
145 [](const RedirectStat& x, const RedirectStat& y) { 121 [](const RedirectStat& x, const RedirectStat& y) {
146 return ComputeRedirectScore(x) > ComputeRedirectScore(y); 122 return ComputeRedirectScore(x) > ComputeRedirectScore(y);
147 }); 123 });
148 } 124 }
149 125
150 ResourcePrefetchPredictorTables::PrefetchData::PrefetchData(
151 PrefetchKeyType i_key_type,
152 const std::string& i_primary_key)
153 : key_type(i_key_type),
154 primary_key(i_primary_key) {
155 }
156
157 ResourcePrefetchPredictorTables::PrefetchData::PrefetchData(
158 const PrefetchData& other)
159 : key_type(other.key_type),
160 primary_key(other.primary_key),
161 last_visit(other.last_visit),
162 resources(other.resources) {
163 }
164
165 ResourcePrefetchPredictorTables::PrefetchData::~PrefetchData() {
166 }
167
168 void ResourcePrefetchPredictorTables::GetAllData( 126 void ResourcePrefetchPredictorTables::GetAllData(
169 PrefetchDataMap* url_data_map, 127 PrefetchDataMap* url_data_map,
170 PrefetchDataMap* host_data_map, 128 PrefetchDataMap* host_data_map,
171 RedirectDataMap* url_redirect_data_map, 129 RedirectDataMap* url_redirect_data_map,
172 RedirectDataMap* host_redirect_data_map) { 130 RedirectDataMap* host_redirect_data_map) {
173 DCHECK_CURRENTLY_ON(BrowserThread::DB); 131 DCHECK_CURRENTLY_ON(BrowserThread::DB);
174 if (CantAccessDatabase()) 132 if (CantAccessDatabase())
175 return; 133 return;
176 134
177 DCHECK(url_data_map); 135 DCHECK(url_data_map);
178 DCHECK(host_data_map); 136 DCHECK(host_data_map);
179 DCHECK(url_redirect_data_map); 137 DCHECK(url_redirect_data_map);
180 DCHECK(host_redirect_data_map); 138 DCHECK(host_redirect_data_map);
181 url_data_map->clear(); 139 url_data_map->clear();
182 host_data_map->clear(); 140 host_data_map->clear();
183 url_redirect_data_map->clear(); 141 url_redirect_data_map->clear();
184 host_redirect_data_map->clear(); 142 host_redirect_data_map->clear();
185 143
186 std::vector<std::string> urls_to_delete, hosts_to_delete; 144 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_URL, url_data_map);
187 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_URL, url_data_map, 145 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_HOST, host_data_map);
188 &urls_to_delete);
189 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_HOST, host_data_map,
190 &hosts_to_delete);
191 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_URL, url_redirect_data_map); 146 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_URL, url_redirect_data_map);
192 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, host_redirect_data_map); 147 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, host_redirect_data_map);
193
194 if (!urls_to_delete.empty() || !hosts_to_delete.empty())
195 DeleteResourceData(urls_to_delete, hosts_to_delete);
196 } 148 }
197 149
198 void ResourcePrefetchPredictorTables::UpdateData( 150 void ResourcePrefetchPredictorTables::UpdateData(
199 const PrefetchData& url_data, 151 const PrefetchData& url_data,
200 const PrefetchData& host_data, 152 const PrefetchData& host_data,
201 const RedirectData& url_redirect_data, 153 const RedirectData& url_redirect_data,
202 const RedirectData& host_redirect_data) { 154 const RedirectData& host_redirect_data) {
203 DCHECK_CURRENTLY_ON(BrowserThread::DB); 155 DCHECK_CURRENTLY_ON(BrowserThread::DB);
204 if (CantAccessDatabase()) 156 if (CantAccessDatabase())
205 return; 157 return;
206 158
207 DCHECK(!url_data.is_host() && host_data.is_host()); 159 DCHECK(url_data.has_primary_key() || host_data.has_primary_key() ||
208 DCHECK(!url_data.primary_key.empty() || !host_data.primary_key.empty() ||
209 url_redirect_data.has_primary_key() || 160 url_redirect_data.has_primary_key() ||
210 host_redirect_data.has_primary_key()); 161 host_redirect_data.has_primary_key());
211 162
212 DB()->BeginTransaction(); 163 DB()->BeginTransaction();
213 164
214 bool success = 165 bool success =
215 (url_data.primary_key.empty() || 166 (!url_data.has_primary_key() ||
216 UpdateResourceDataHelper(PREFETCH_KEY_TYPE_URL, url_data)) && 167 UpdateDataHelper(PREFETCH_KEY_TYPE_URL, PrefetchDataType::RESOURCE,
217 (host_data.primary_key.empty() || 168 url_data.primary_key(), url_data)) &&
218 UpdateResourceDataHelper(PREFETCH_KEY_TYPE_HOST, host_data)) && 169 (!host_data.has_primary_key() ||
170 UpdateDataHelper(PREFETCH_KEY_TYPE_HOST, PrefetchDataType::RESOURCE,
171 host_data.primary_key(), host_data)) &&
219 (!url_redirect_data.has_primary_key() || 172 (!url_redirect_data.has_primary_key() ||
220 UpdateRedirectDataHelper(PREFETCH_KEY_TYPE_URL, url_redirect_data)) && 173 UpdateDataHelper(PREFETCH_KEY_TYPE_URL, PrefetchDataType::REDIRECT,
174 url_redirect_data.primary_key(), url_redirect_data)) &&
221 (!host_redirect_data.has_primary_key() || 175 (!host_redirect_data.has_primary_key() ||
222 UpdateRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, host_redirect_data)); 176 UpdateDataHelper(PREFETCH_KEY_TYPE_HOST, PrefetchDataType::REDIRECT,
177 host_redirect_data.primary_key(), host_redirect_data));
223 if (!success) 178 if (!success)
224 DB()->RollbackTransaction(); 179 DB()->RollbackTransaction();
225 else 180 else
226 DB()->CommitTransaction(); 181 DB()->CommitTransaction();
227 } 182 }
228 183
229 void ResourcePrefetchPredictorTables::DeleteResourceData( 184 void ResourcePrefetchPredictorTables::DeleteResourceData(
230 const std::vector<std::string>& urls, 185 const std::vector<std::string>& urls,
231 const std::vector<std::string>& hosts) { 186 const std::vector<std::string>& hosts) {
232 DCHECK_CURRENTLY_ON(BrowserThread::DB); 187 DCHECK_CURRENTLY_ON(BrowserThread::DB);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 const std::string& key, 225 const std::string& key,
271 PrefetchKeyType key_type) { 226 PrefetchKeyType key_type) {
272 DCHECK_CURRENTLY_ON(BrowserThread::DB); 227 DCHECK_CURRENTLY_ON(BrowserThread::DB);
273 if (CantAccessDatabase()) 228 if (CantAccessDatabase())
274 return; 229 return;
275 230
276 DeleteDataHelper(key_type, PrefetchDataType::REDIRECT, {key}); 231 DeleteDataHelper(key_type, PrefetchDataType::REDIRECT, {key});
277 } 232 }
278 233
279 void ResourcePrefetchPredictorTables::DeleteAllData() { 234 void ResourcePrefetchPredictorTables::DeleteAllData() {
235 DCHECK_CURRENTLY_ON(BrowserThread::DB);
280 if (CantAccessDatabase()) 236 if (CantAccessDatabase())
281 return; 237 return;
282 238
283 Statement deleter; 239 Statement deleter;
284 for (const char* table_name : 240 for (const char* table_name :
285 {kUrlResourceTableName, kUrlMetadataTableName, kUrlRedirectTableName, 241 {kUrlResourceTableName, kUrlRedirectTableName, kHostResourceTableName,
286 kHostResourceTableName, kHostMetadataTableName,
287 kHostRedirectTableName}) { 242 kHostRedirectTableName}) {
288 deleter.Assign(DB()->GetUniqueStatement( 243 deleter.Assign(DB()->GetUniqueStatement(
289 base::StringPrintf("DELETE FROM %s", table_name).c_str())); 244 base::StringPrintf("DELETE FROM %s", table_name).c_str()));
290 deleter.Run(); 245 deleter.Run();
291 } 246 }
292 } 247 }
293 248
294 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() 249 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables()
295 : PredictorTableBase() { 250 : PredictorTableBase() {}
296 }
297 251
298 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() { 252 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {}
299 }
300 253
301 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper( 254 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper(
302 PrefetchKeyType key_type, 255 PrefetchKeyType key_type,
303 PrefetchDataMap* data_map, 256 PrefetchDataMap* data_map) {
304 std::vector<std::string>* to_delete) { 257 // Read the resources table and organize it per primary key.
305 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 258 const char* table_name = GetTableName(key_type, PrefetchDataType::RESOURCE);
259 Statement resource_reader(DB()->GetUniqueStatement(
260 base::StringPrintf("SELECT * FROM %s", table_name).c_str()));
306 261
307 // Read the resources table and organize it per primary key. 262 PrefetchData data;
308 const char* resource_table_name = is_host ? kHostResourceTableName : 263 std::string key;
309 kUrlResourceTableName; 264 while (StepAndInitializeProtoData(&resource_reader, &key, &data)) {
310 Statement resource_reader(DB()->GetUniqueStatement( 265 data_map->insert(std::make_pair(key, data));
311 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str())); 266 DCHECK_EQ(data.primary_key(), key);
312
313 ResourceData resource;
314 std::string primary_key;
315 while (StepAndInitializeResourceData(&resource_reader, &resource,
316 &primary_key)) {
317 PrefetchDataMap::iterator it = data_map->find(primary_key);
318 if (it == data_map->end()) {
319 it = data_map->insert(std::make_pair(
320 primary_key, PrefetchData(key_type, primary_key))).first;
321 }
322 it->second.resources.push_back(resource);
323 } 267 }
324 268
325 // Sort each of the resource row vectors by score. 269 // Sort each of the resource vectors by score.
326 for (auto& kv : *data_map) 270 for (auto& kv : *data_map) {
327 SortResources(&(kv.second.resources)); 271 SortResources(&(kv.second));
328
329 // Read the metadata and keep track of entries that have metadata, but no
330 // resource entries, so they can be deleted.
331 const char* metadata_table_name =
332 is_host ? kHostMetadataTableName : kUrlMetadataTableName;
333 Statement metadata_reader(DB()->GetUniqueStatement(
334 base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str()));
335
336 while (metadata_reader.Step()) {
337 std::string primary_key = metadata_reader.ColumnString(0);
338
339 PrefetchDataMap::iterator it = data_map->find(primary_key);
340 if (it != data_map->end()) {
341 int64_t last_visit = metadata_reader.ColumnInt64(1);
342 it->second.last_visit = base::Time::FromInternalValue(last_visit);
343 } else {
344 to_delete->push_back(primary_key);
345 }
346 } 272 }
347 } 273 }
348 274
349 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper( 275 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper(
350 PrefetchKeyType key_type, 276 PrefetchKeyType key_type,
351 RedirectDataMap* redirect_map) { 277 RedirectDataMap* data_map) {
352 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 278 // Read the redirects table and organize it per primary key.
353 279 const char* table_name = GetTableName(key_type, PrefetchDataType::REDIRECT);
354 const char* redirect_table_name =
355 is_host ? kHostRedirectTableName : kUrlRedirectTableName;
356 Statement redirect_reader(DB()->GetUniqueStatement( 280 Statement redirect_reader(DB()->GetUniqueStatement(
357 base::StringPrintf("SELECT * FROM %s", redirect_table_name).c_str())); 281 base::StringPrintf("SELECT * FROM %s", table_name).c_str()));
358 282
359 RedirectData data; 283 RedirectData data;
360 std::string primary_key; 284 std::string key;
361 while (StepAndInitializeRedirectData(&redirect_reader, &data, &primary_key)) { 285 while (StepAndInitializeProtoData(&redirect_reader, &key, &data)) {
362 auto result = redirect_map->insert(std::make_pair(primary_key, data)); 286 data_map->insert(std::make_pair(key, data));
363 DCHECK(result.second); 287 DCHECK_EQ(data.primary_key(), key);
288 }
289
290 // Sort each of the redirect vectors by score.
291 for (auto& kv : *data_map) {
292 SortRedirects(&(kv.second));
364 } 293 }
365 } 294 }
366 295
367 bool ResourcePrefetchPredictorTables::UpdateResourceDataHelper( 296 bool ResourcePrefetchPredictorTables::UpdateDataHelper(
368 PrefetchKeyType key_type, 297 PrefetchKeyType key_type,
369 const PrefetchData& data) { 298 PrefetchDataType data_type,
370 DCHECK(!data.primary_key.empty()); 299 const std::string& key,
371 300 const MessageLite& data) {
372 if (!StringsAreSmallerThanDBLimit(data)) {
373 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
374 return false;
375 }
376
377 // Delete the older data from both the tables.
378 std::unique_ptr<Statement> deleter(GetTableUpdateStatement(
379 key_type, PrefetchDataType::RESOURCE, TableOperationType::REMOVE));
380 deleter->BindString(0, data.primary_key);
381 if (!deleter->Run())
382 return false;
383
384 deleter = GetTableUpdateStatement(key_type, PrefetchDataType::METADATA,
385 TableOperationType::REMOVE);
386 deleter->BindString(0, data.primary_key);
387 if (!deleter->Run())
388 return false;
389
390 // Add the new data to the tables.
391 for (const ResourceData& resource : data.resources) {
392 std::unique_ptr<Statement> resource_inserter(GetTableUpdateStatement(
393 key_type, PrefetchDataType::RESOURCE, TableOperationType::INSERT));
394 BindResourceDataToStatement(resource, data.primary_key,
395 resource_inserter.get());
396 if (!resource_inserter->Run())
397 return false;
398 }
399
400 std::unique_ptr<Statement> metadata_inserter(GetTableUpdateStatement(
401 key_type, PrefetchDataType::METADATA, TableOperationType::INSERT));
402 metadata_inserter->BindString(0, data.primary_key);
403 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue());
404 return metadata_inserter->Run();
405 }
406
407 bool ResourcePrefetchPredictorTables::UpdateRedirectDataHelper(
408 PrefetchKeyType key_type,
409 const RedirectData& data) {
410 DCHECK(data.has_primary_key());
411
412 if (!StringsAreSmallerThanDBLimit(data)) {
413 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
414 return false;
415 }
416
417 // Delete the older data from the table. 301 // Delete the older data from the table.
418 std::unique_ptr<Statement> deleter(GetTableUpdateStatement( 302 std::unique_ptr<Statement> deleter(
419 key_type, PrefetchDataType::REDIRECT, TableOperationType::REMOVE)); 303 GetTableUpdateStatement(key_type, data_type, TableOperationType::REMOVE));
420 deleter->BindString(0, data.primary_key()); 304 deleter->BindString(0, key);
421 if (!deleter->Run()) 305 if (!deleter->Run())
422 return false; 306 return false;
423 307
424 // Add the new data to the table. 308 // Add the new data to the table.
425 std::unique_ptr<Statement> inserter(GetTableUpdateStatement( 309 std::unique_ptr<Statement> inserter(
426 key_type, PrefetchDataType::REDIRECT, TableOperationType::INSERT)); 310 GetTableUpdateStatement(key_type, data_type, TableOperationType::INSERT));
427 BindRedirectDataToStatement(data, inserter.get()); 311 BindProtoDataToStatement(key, data, inserter.get());
428 return inserter->Run(); 312 return inserter->Run();
429 } 313 }
430 314
431 void ResourcePrefetchPredictorTables::DeleteDataHelper( 315 void ResourcePrefetchPredictorTables::DeleteDataHelper(
432 PrefetchKeyType key_type, 316 PrefetchKeyType key_type,
433 PrefetchDataType data_type, 317 PrefetchDataType data_type,
434 const std::vector<std::string>& keys) { 318 const std::vector<std::string>& keys) {
435 bool is_resource = data_type == PrefetchDataType::RESOURCE;
436
437 for (const std::string& key : keys) { 319 for (const std::string& key : keys) {
438 std::unique_ptr<Statement> deleter(GetTableUpdateStatement( 320 std::unique_ptr<Statement> deleter(GetTableUpdateStatement(
439 key_type, data_type, TableOperationType::REMOVE)); 321 key_type, data_type, TableOperationType::REMOVE));
440 deleter->BindString(0, key); 322 deleter->BindString(0, key);
441 deleter->Run(); 323 deleter->Run();
442
443 if (is_resource) {
444 // Delete corresponding resource metadata as well.
445 deleter = GetTableUpdateStatement(key_type, PrefetchDataType::METADATA,
446 TableOperationType::REMOVE);
447 deleter->BindString(0, key);
448 deleter->Run();
449 }
450 } 324 }
451 } 325 }
452 326
453 // static 327 // static
454 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
455 const PrefetchData& data) {
456 if (data.primary_key.length() > kMaxStringLength)
457 return false;
458
459 for (const ResourceData& resource : data.resources) {
460 if (resource.resource_url().length() > kMaxStringLength)
461 return false;
462 }
463 return true;
464 }
465
466 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
467 const RedirectData& data) {
468 if (data.primary_key().length() > kMaxStringLength)
469 return false;
470
471 for (const RedirectStat& redirect : data.redirect_endpoints()) {
472 if (redirect.url().length() > kMaxStringLength)
473 return false;
474 }
475 return true;
476 }
477
478 // static
479 float ResourcePrefetchPredictorTables::ComputeResourceScore( 328 float ResourcePrefetchPredictorTables::ComputeResourceScore(
480 const ResourceData& data) { 329 const ResourceData& data) {
481 // The score is calculated so that when the rows are sorted, stylesheets, 330 // The score is calculated so that when the rows are sorted, stylesheets,
482 // scripts and fonts appear first, sorted by position(ascending) and then the 331 // scripts and fonts appear first, sorted by position(ascending) and then the
483 // rest of the resources sorted by position (ascending). 332 // rest of the resources sorted by position (ascending).
484 static const int kMaxResourcesPerType = 100; 333 static const int kMaxResourcesPerType = 100;
485 switch (data.resource_type()) { 334 switch (data.resource_type()) {
486 case ResourceData::RESOURCE_TYPE_STYLESHEET: 335 case ResourceData::RESOURCE_TYPE_STYLESHEET:
487 case ResourceData::RESOURCE_TYPE_SCRIPT: 336 case ResourceData::RESOURCE_TYPE_SCRIPT:
488 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE: 337 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE:
(...skipping 14 matching lines...) Expand all
503 } 352 }
504 353
505 // static 354 // static
506 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( 355 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated(
507 sql::Connection* db) { 356 sql::Connection* db) {
508 int version = GetDatabaseVersion(db); 357 int version = GetDatabaseVersion(db);
509 bool success = true; 358 bool success = true;
510 // Too new is also a problem. 359 // Too new is also a problem.
511 bool incompatible_version = version != kDatabaseVersion; 360 bool incompatible_version = version != kDatabaseVersion;
512 361
362 // These are deprecated tables but they still have to be removed if present.
363 const char kUrlMetadataTableName[] =
364 "resource_prefetch_predictor_url_metadata";
365 const char kHostMetadataTableName[] =
366 "resource_prefetch_predictor_host_metadata";
367
513 if (incompatible_version) { 368 if (incompatible_version) {
514 for (const char* table_name : 369 for (const char* table_name :
515 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName, 370 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName,
516 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName, 371 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName,
517 kHostMetadataTableName}) { 372 kHostMetadataTableName}) {
518 success = 373 success =
519 success && 374 success &&
520 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name) 375 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name)
521 .c_str()); 376 .c_str());
522 } 377 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 if (CantAccessDatabase()) 419 if (CantAccessDatabase())
565 return; 420 return;
566 421
567 // Database initialization is all-or-nothing. 422 // Database initialization is all-or-nothing.
568 sql::Connection* db = DB(); 423 sql::Connection* db = DB();
569 sql::Transaction transaction{db}; 424 sql::Transaction transaction{db};
570 bool success = transaction.Begin(); 425 bool success = transaction.Begin();
571 426
572 success = success && DropTablesIfOutdated(db); 427 success = success && DropTablesIfOutdated(db);
573 428
574 success = 429 for (const char* table_name :
575 success && 430 {kUrlResourceTableName, kHostResourceTableName, kUrlRedirectTableName,
576 (db->DoesTableExist(kUrlResourceTableName) || 431 kHostRedirectTableName}) {
577 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, 432 success = success &&
578 kUrlResourceTableName) 433 (db->DoesTableExist(table_name) ||
579 .c_str())) && 434 db->Execute(base::StringPrintf(
580 (db->DoesTableExist(kUrlMetadataTableName) || 435 kCreateProtoTableStatementTemplate, table_name)
581 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, 436 .c_str()));
582 kUrlMetadataTableName) 437 }
583 .c_str())) &&
584 (db->DoesTableExist(kUrlRedirectTableName) ||
585 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
586 kUrlRedirectTableName)
587 .c_str())) &&
588 (db->DoesTableExist(kHostResourceTableName) ||
589 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
590 kHostResourceTableName)
591 .c_str())) &&
592 (db->DoesTableExist(kHostMetadataTableName) ||
593 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
594 kHostMetadataTableName)
595 .c_str())) &&
596 (db->DoesTableExist(kHostRedirectTableName) ||
597 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
598 kHostRedirectTableName)
599 .c_str()));
600 438
601 if (success) 439 if (success)
602 success = transaction.Commit(); 440 success = transaction.Commit();
603 else 441 else
604 transaction.Rollback(); 442 transaction.Rollback();
605 443
606 if (!success) 444 if (!success)
607 ResetDB(); 445 ResetDB();
608 } 446 }
609 447
(...skipping 16 matching lines...) Expand all
626 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount", 464 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount",
627 statement.ColumnInt(0)); 465 statement.ColumnInt(0));
628 } 466 }
629 467
630 std::unique_ptr<Statement> 468 std::unique_ptr<Statement>
631 ResourcePrefetchPredictorTables::GetTableUpdateStatement( 469 ResourcePrefetchPredictorTables::GetTableUpdateStatement(
632 PrefetchKeyType key_type, 470 PrefetchKeyType key_type,
633 PrefetchDataType data_type, 471 PrefetchDataType data_type,
634 TableOperationType op_type) { 472 TableOperationType op_type) {
635 sql::StatementID id(__FILE__, key_type | (static_cast<int>(data_type) << 1) | 473 sql::StatementID id(__FILE__, key_type | (static_cast<int>(data_type) << 1) |
636 (static_cast<int>(op_type) << 3)); 474 (static_cast<int>(op_type) << 2));
637 const char* statement_template = 475 const char* statement_template = (op_type == TableOperationType::REMOVE
638 GetTableUpdateStatementTemplate(op_type, data_type); 476 ? kDeleteProtoTableStatementTemplate
639 const char* table_name = 477 : kInsertProtoTableStatementTemplate);
640 GetTableUpdateStatementTableName(key_type, data_type); 478 const char* table_name = GetTableName(key_type, data_type);
641 return base::MakeUnique<Statement>(DB()->GetCachedStatement( 479 return base::MakeUnique<Statement>(DB()->GetCachedStatement(
642 id, base::StringPrintf(statement_template, table_name).c_str())); 480 id, base::StringPrintf(statement_template, table_name).c_str()));
643 } 481 }
644 482
645 // static 483 // static
646 const char* ResourcePrefetchPredictorTables::GetTableUpdateStatementTemplate( 484 const char* ResourcePrefetchPredictorTables::GetTableName(
647 TableOperationType op_type,
648 PrefetchDataType data_type) {
649 switch (op_type) {
650 case TableOperationType::REMOVE:
651 return kDeleteStatementTemplate;
652 case TableOperationType::INSERT:
653 switch (data_type) {
654 case PrefetchDataType::RESOURCE:
655 return kInsertResourceTableStatementTemplate;
656 case PrefetchDataType::REDIRECT:
657 return kInsertRedirectTableStatementTemplate;
658 case PrefetchDataType::METADATA:
659 return kInsertMetadataTableStatementTemplate;
660 }
661 }
662
663 NOTREACHED();
664 return nullptr;
665 }
666
667 // static
668 const char* ResourcePrefetchPredictorTables::GetTableUpdateStatementTableName(
669 PrefetchKeyType key_type, 485 PrefetchKeyType key_type,
670 PrefetchDataType data_type) { 486 PrefetchDataType data_type) {
671 DCHECK(key_type == PREFETCH_KEY_TYPE_URL ||
672 key_type == PREFETCH_KEY_TYPE_HOST);
673 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 487 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
674 switch (data_type) { 488 switch (data_type) {
675 case PrefetchDataType::RESOURCE: 489 case PrefetchDataType::RESOURCE:
676 return is_host ? kHostResourceTableName : kUrlResourceTableName; 490 return is_host ? kHostResourceTableName : kUrlResourceTableName;
677 case PrefetchDataType::REDIRECT: 491 case PrefetchDataType::REDIRECT:
678 return is_host ? kHostRedirectTableName : kUrlRedirectTableName; 492 return is_host ? kHostRedirectTableName : kUrlRedirectTableName;
679 case PrefetchDataType::METADATA:
680 return is_host ? kHostMetadataTableName : kUrlMetadataTableName;
681 } 493 }
682 494
683 NOTREACHED(); 495 NOTREACHED();
684 return nullptr; 496 return nullptr;
685 } 497 }
686 498
687 } // namespace predictors 499 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698