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

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

Issue 2388783002: predictors: Refactor resource_prefetch_predictor_tables. (Closed)
Patch Set: Rebase. 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 // Decreasing score ordering. 99 // Decreasing score ordering.
138 return ComputeResourceScore(x) > ComputeResourceScore(y); 100 return ComputeResourceScore(x) > ComputeResourceScore(y);
139 }); 101 });
140 } 102 }
141 103
142 // static 104 // static
143 void ResourcePrefetchPredictorTables::SortRedirects( 105 void ResourcePrefetchPredictorTables::TrimRedirects(
144 std::vector<RedirectStat>* redirects) { 106 RedirectData* data,
145 std::sort(redirects->begin(), redirects->end(), 107 size_t max_consecutive_misses) {
108 auto new_end =
109 std::remove_if(data->mutable_redirect_endpoints()->begin(),
110 data->mutable_redirect_endpoints()->end(),
111 [max_consecutive_misses](const RedirectStat& x) {
112 return x.consecutive_misses() >= max_consecutive_misses;
113 });
114 data->mutable_redirect_endpoints()->erase(
115 new_end, data->mutable_redirect_endpoints()->end());
116 }
117
118 // static
119 void ResourcePrefetchPredictorTables::SortRedirects(RedirectData* data) {
120 std::sort(data->mutable_redirect_endpoints()->begin(),
121 data->mutable_redirect_endpoints()->end(),
146 [](const RedirectStat& x, const RedirectStat& y) { 122 [](const RedirectStat& x, const RedirectStat& y) {
147 // Decreasing score ordering. 123 // Decreasing score ordering.
148 return ComputeRedirectScore(x) > ComputeRedirectScore(y); 124 return ComputeRedirectScore(x) > ComputeRedirectScore(y);
149 }); 125 });
150 } 126 }
151 127
152 ResourcePrefetchPredictorTables::PrefetchData::PrefetchData(
153 PrefetchKeyType i_key_type,
154 const std::string& i_primary_key)
155 : key_type(i_key_type),
156 primary_key(i_primary_key) {
157 }
158
159 ResourcePrefetchPredictorTables::PrefetchData::PrefetchData(
160 const PrefetchData& other)
161 : key_type(other.key_type),
162 primary_key(other.primary_key),
163 last_visit(other.last_visit),
164 resources(other.resources) {
165 }
166
167 ResourcePrefetchPredictorTables::PrefetchData::~PrefetchData() {
168 }
169
170 void ResourcePrefetchPredictorTables::GetAllData( 128 void ResourcePrefetchPredictorTables::GetAllData(
171 PrefetchDataMap* url_data_map, 129 PrefetchDataMap* url_data_map,
172 PrefetchDataMap* host_data_map, 130 PrefetchDataMap* host_data_map,
173 RedirectDataMap* url_redirect_data_map, 131 RedirectDataMap* url_redirect_data_map,
174 RedirectDataMap* host_redirect_data_map) { 132 RedirectDataMap* host_redirect_data_map) {
175 DCHECK_CURRENTLY_ON(BrowserThread::DB); 133 DCHECK_CURRENTLY_ON(BrowserThread::DB);
176 if (CantAccessDatabase()) 134 if (CantAccessDatabase())
177 return; 135 return;
178 136
179 DCHECK(url_data_map); 137 DCHECK(url_data_map);
180 DCHECK(host_data_map); 138 DCHECK(host_data_map);
181 DCHECK(url_redirect_data_map); 139 DCHECK(url_redirect_data_map);
182 DCHECK(host_redirect_data_map); 140 DCHECK(host_redirect_data_map);
183 url_data_map->clear(); 141 url_data_map->clear();
184 host_data_map->clear(); 142 host_data_map->clear();
185 url_redirect_data_map->clear(); 143 url_redirect_data_map->clear();
186 host_redirect_data_map->clear(); 144 host_redirect_data_map->clear();
187 145
188 std::vector<std::string> urls_to_delete, hosts_to_delete; 146 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_URL, url_data_map);
189 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_URL, url_data_map, 147 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_HOST, host_data_map);
190 &urls_to_delete);
191 GetAllResourceDataHelper(PREFETCH_KEY_TYPE_HOST, host_data_map,
192 &hosts_to_delete);
193 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_URL, url_redirect_data_map); 148 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_URL, url_redirect_data_map);
194 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, host_redirect_data_map); 149 GetAllRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, host_redirect_data_map);
195
196 if (!urls_to_delete.empty() || !hosts_to_delete.empty())
197 DeleteResourceData(urls_to_delete, hosts_to_delete);
198 } 150 }
199 151
200 void ResourcePrefetchPredictorTables::UpdateData( 152 void ResourcePrefetchPredictorTables::UpdateData(
201 const PrefetchData& url_data, 153 const PrefetchData& url_data,
202 const PrefetchData& host_data, 154 const PrefetchData& host_data,
203 const RedirectData& url_redirect_data, 155 const RedirectData& url_redirect_data,
204 const RedirectData& host_redirect_data) { 156 const RedirectData& host_redirect_data) {
205 DCHECK_CURRENTLY_ON(BrowserThread::DB); 157 DCHECK_CURRENTLY_ON(BrowserThread::DB);
206 if (CantAccessDatabase()) 158 if (CantAccessDatabase())
207 return; 159 return;
208 160
209 DCHECK(!url_data.is_host() && host_data.is_host()); 161 DCHECK(url_data.has_primary_key() || host_data.has_primary_key() ||
210 DCHECK(!url_data.primary_key.empty() || !host_data.primary_key.empty() ||
211 url_redirect_data.has_primary_key() || 162 url_redirect_data.has_primary_key() ||
212 host_redirect_data.has_primary_key()); 163 host_redirect_data.has_primary_key());
213 164
214 DB()->BeginTransaction(); 165 DB()->BeginTransaction();
215 166
216 bool success = 167 bool success =
217 (url_data.primary_key.empty() || 168 (!url_data.has_primary_key() ||
218 UpdateResourceDataHelper(PREFETCH_KEY_TYPE_URL, url_data)) && 169 UpdateDataHelper(PREFETCH_KEY_TYPE_URL, PrefetchDataType::RESOURCE,
219 (host_data.primary_key.empty() || 170 url_data.primary_key(), url_data)) &&
220 UpdateResourceDataHelper(PREFETCH_KEY_TYPE_HOST, host_data)) && 171 (!host_data.has_primary_key() ||
172 UpdateDataHelper(PREFETCH_KEY_TYPE_HOST, PrefetchDataType::RESOURCE,
173 host_data.primary_key(), host_data)) &&
221 (!url_redirect_data.has_primary_key() || 174 (!url_redirect_data.has_primary_key() ||
222 UpdateRedirectDataHelper(PREFETCH_KEY_TYPE_URL, url_redirect_data)) && 175 UpdateDataHelper(PREFETCH_KEY_TYPE_URL, PrefetchDataType::REDIRECT,
176 url_redirect_data.primary_key(), url_redirect_data)) &&
223 (!host_redirect_data.has_primary_key() || 177 (!host_redirect_data.has_primary_key() ||
224 UpdateRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, host_redirect_data)); 178 UpdateDataHelper(PREFETCH_KEY_TYPE_HOST, PrefetchDataType::REDIRECT,
179 host_redirect_data.primary_key(), host_redirect_data));
225 if (!success) 180 if (!success)
226 DB()->RollbackTransaction(); 181 DB()->RollbackTransaction();
227 else 182 else
228 DB()->CommitTransaction(); 183 DB()->CommitTransaction();
229 } 184 }
230 185
231 void ResourcePrefetchPredictorTables::DeleteResourceData( 186 void ResourcePrefetchPredictorTables::DeleteResourceData(
232 const std::vector<std::string>& urls, 187 const std::vector<std::string>& urls,
233 const std::vector<std::string>& hosts) { 188 const std::vector<std::string>& hosts) {
234 DCHECK_CURRENTLY_ON(BrowserThread::DB); 189 DCHECK_CURRENTLY_ON(BrowserThread::DB);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 const std::string& key, 227 const std::string& key,
273 PrefetchKeyType key_type) { 228 PrefetchKeyType key_type) {
274 DCHECK_CURRENTLY_ON(BrowserThread::DB); 229 DCHECK_CURRENTLY_ON(BrowserThread::DB);
275 if (CantAccessDatabase()) 230 if (CantAccessDatabase())
276 return; 231 return;
277 232
278 DeleteDataHelper(key_type, PrefetchDataType::REDIRECT, {key}); 233 DeleteDataHelper(key_type, PrefetchDataType::REDIRECT, {key});
279 } 234 }
280 235
281 void ResourcePrefetchPredictorTables::DeleteAllData() { 236 void ResourcePrefetchPredictorTables::DeleteAllData() {
237 DCHECK_CURRENTLY_ON(BrowserThread::DB);
282 if (CantAccessDatabase()) 238 if (CantAccessDatabase())
283 return; 239 return;
284 240
285 Statement deleter; 241 Statement deleter;
286 for (const char* table_name : 242 for (const char* table_name :
287 {kUrlResourceTableName, kUrlMetadataTableName, kUrlRedirectTableName, 243 {kUrlResourceTableName, kUrlRedirectTableName, kHostResourceTableName,
288 kHostResourceTableName, kHostMetadataTableName,
289 kHostRedirectTableName}) { 244 kHostRedirectTableName}) {
290 deleter.Assign(DB()->GetUniqueStatement( 245 deleter.Assign(DB()->GetUniqueStatement(
291 base::StringPrintf("DELETE FROM %s", table_name).c_str())); 246 base::StringPrintf("DELETE FROM %s", table_name).c_str()));
292 deleter.Run(); 247 deleter.Run();
293 } 248 }
294 } 249 }
295 250
296 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() 251 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables()
297 : PredictorTableBase() { 252 : PredictorTableBase() {}
298 }
299 253
300 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() { 254 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {}
301 }
302 255
303 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper( 256 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper(
304 PrefetchKeyType key_type, 257 PrefetchKeyType key_type,
305 PrefetchDataMap* data_map, 258 PrefetchDataMap* data_map) {
306 std::vector<std::string>* to_delete) { 259 // Read the resources table and organize it per primary key.
307 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 260 const char* table_name = GetTableName(key_type, PrefetchDataType::RESOURCE);
261 Statement resource_reader(DB()->GetUniqueStatement(
262 base::StringPrintf("SELECT * FROM %s", table_name).c_str()));
308 263
309 // Read the resources table and organize it per primary key. 264 PrefetchData data;
310 const char* resource_table_name = is_host ? kHostResourceTableName : 265 std::string key;
311 kUrlResourceTableName; 266 while (StepAndInitializeProtoData(&resource_reader, &key, &data)) {
312 Statement resource_reader(DB()->GetUniqueStatement( 267 data_map->insert(std::make_pair(key, data));
313 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str())); 268 DCHECK_EQ(data.primary_key(), key);
314
315 ResourceData resource;
316 std::string primary_key;
317 while (StepAndInitializeResourceData(&resource_reader, &resource,
318 &primary_key)) {
319 PrefetchDataMap::iterator it = data_map->find(primary_key);
320 if (it == data_map->end()) {
321 it = data_map->insert(std::make_pair(
322 primary_key, PrefetchData(key_type, primary_key))).first;
323 }
324 it->second.resources.push_back(resource);
325 } 269 }
326 270
327 // Sort each of the resource row vectors by score. 271 // Sort each of the resource vectors by score.
328 for (auto& kv : *data_map) 272 for (auto& kv : *data_map) {
329 SortResources(&(kv.second.resources)); 273 SortResources(&(kv.second));
330
331 // Read the metadata and keep track of entries that have metadata, but no
332 // resource entries, so they can be deleted.
333 const char* metadata_table_name =
334 is_host ? kHostMetadataTableName : kUrlMetadataTableName;
335 Statement metadata_reader(DB()->GetUniqueStatement(
336 base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str()));
337
338 while (metadata_reader.Step()) {
339 std::string primary_key = metadata_reader.ColumnString(0);
340
341 PrefetchDataMap::iterator it = data_map->find(primary_key);
342 if (it != data_map->end()) {
343 int64_t last_visit = metadata_reader.ColumnInt64(1);
344 it->second.last_visit = base::Time::FromInternalValue(last_visit);
345 } else {
346 to_delete->push_back(primary_key);
347 }
348 } 274 }
349 } 275 }
350 276
351 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper( 277 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper(
352 PrefetchKeyType key_type, 278 PrefetchKeyType key_type,
353 RedirectDataMap* redirect_map) { 279 RedirectDataMap* data_map) {
354 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 280 // Read the redirects table and organize it per primary key.
355 281 const char* table_name = GetTableName(key_type, PrefetchDataType::REDIRECT);
356 const char* redirect_table_name =
357 is_host ? kHostRedirectTableName : kUrlRedirectTableName;
358 Statement redirect_reader(DB()->GetUniqueStatement( 282 Statement redirect_reader(DB()->GetUniqueStatement(
359 base::StringPrintf("SELECT * FROM %s", redirect_table_name).c_str())); 283 base::StringPrintf("SELECT * FROM %s", table_name).c_str()));
360 284
361 RedirectData data; 285 RedirectData data;
362 std::string primary_key; 286 std::string key;
363 while (StepAndInitializeRedirectData(&redirect_reader, &data, &primary_key)) { 287 while (StepAndInitializeProtoData(&redirect_reader, &key, &data)) {
364 auto result = redirect_map->insert(std::make_pair(primary_key, data)); 288 data_map->insert(std::make_pair(key, data));
365 DCHECK(result.second); 289 DCHECK_EQ(data.primary_key(), key);
290 }
291
292 // Sort each of the redirect vectors by score.
293 for (auto& kv : *data_map) {
294 SortRedirects(&(kv.second));
366 } 295 }
367 } 296 }
368 297
369 bool ResourcePrefetchPredictorTables::UpdateResourceDataHelper( 298 bool ResourcePrefetchPredictorTables::UpdateDataHelper(
370 PrefetchKeyType key_type, 299 PrefetchKeyType key_type,
371 const PrefetchData& data) { 300 PrefetchDataType data_type,
372 DCHECK(!data.primary_key.empty()); 301 const std::string& key,
373 302 const MessageLite& data) {
374 if (!StringsAreSmallerThanDBLimit(data)) {
375 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
376 return false;
377 }
378
379 // Delete the older data from both the tables.
380 std::unique_ptr<Statement> deleter(GetTableUpdateStatement(
381 key_type, PrefetchDataType::RESOURCE, TableOperationType::REMOVE));
382 deleter->BindString(0, data.primary_key);
383 if (!deleter->Run())
384 return false;
385
386 deleter = GetTableUpdateStatement(key_type, PrefetchDataType::METADATA,
387 TableOperationType::REMOVE);
388 deleter->BindString(0, data.primary_key);
389 if (!deleter->Run())
390 return false;
391
392 // Add the new data to the tables.
393 for (const ResourceData& resource : data.resources) {
394 std::unique_ptr<Statement> resource_inserter(GetTableUpdateStatement(
395 key_type, PrefetchDataType::RESOURCE, TableOperationType::INSERT));
396 BindResourceDataToStatement(resource, data.primary_key,
397 resource_inserter.get());
398 if (!resource_inserter->Run())
399 return false;
400 }
401
402 std::unique_ptr<Statement> metadata_inserter(GetTableUpdateStatement(
403 key_type, PrefetchDataType::METADATA, TableOperationType::INSERT));
404 metadata_inserter->BindString(0, data.primary_key);
405 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue());
406 return metadata_inserter->Run();
407 }
408
409 bool ResourcePrefetchPredictorTables::UpdateRedirectDataHelper(
410 PrefetchKeyType key_type,
411 const RedirectData& data) {
412 DCHECK(data.has_primary_key());
413
414 if (!StringsAreSmallerThanDBLimit(data)) {
415 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
416 return false;
417 }
418
419 // Delete the older data from the table. 303 // Delete the older data from the table.
420 std::unique_ptr<Statement> deleter(GetTableUpdateStatement( 304 std::unique_ptr<Statement> deleter(
421 key_type, PrefetchDataType::REDIRECT, TableOperationType::REMOVE)); 305 GetTableUpdateStatement(key_type, data_type, TableOperationType::REMOVE));
422 deleter->BindString(0, data.primary_key()); 306 deleter->BindString(0, key);
423 if (!deleter->Run()) 307 if (!deleter->Run())
424 return false; 308 return false;
425 309
426 // Add the new data to the table. 310 // Add the new data to the table.
427 std::unique_ptr<Statement> inserter(GetTableUpdateStatement( 311 std::unique_ptr<Statement> inserter(
428 key_type, PrefetchDataType::REDIRECT, TableOperationType::INSERT)); 312 GetTableUpdateStatement(key_type, data_type, TableOperationType::INSERT));
429 BindRedirectDataToStatement(data, inserter.get()); 313 BindProtoDataToStatement(key, data, inserter.get());
430 return inserter->Run(); 314 return inserter->Run();
431 } 315 }
432 316
433 void ResourcePrefetchPredictorTables::DeleteDataHelper( 317 void ResourcePrefetchPredictorTables::DeleteDataHelper(
434 PrefetchKeyType key_type, 318 PrefetchKeyType key_type,
435 PrefetchDataType data_type, 319 PrefetchDataType data_type,
436 const std::vector<std::string>& keys) { 320 const std::vector<std::string>& keys) {
437 bool is_resource = data_type == PrefetchDataType::RESOURCE;
438
439 for (const std::string& key : keys) { 321 for (const std::string& key : keys) {
440 std::unique_ptr<Statement> deleter(GetTableUpdateStatement( 322 std::unique_ptr<Statement> deleter(GetTableUpdateStatement(
441 key_type, data_type, TableOperationType::REMOVE)); 323 key_type, data_type, TableOperationType::REMOVE));
442 deleter->BindString(0, key); 324 deleter->BindString(0, key);
443 deleter->Run(); 325 deleter->Run();
444
445 if (is_resource) {
446 // Delete corresponding resource metadata as well.
447 deleter = GetTableUpdateStatement(key_type, PrefetchDataType::METADATA,
448 TableOperationType::REMOVE);
449 deleter->BindString(0, key);
450 deleter->Run();
451 }
452 } 326 }
453 } 327 }
454 328
455 // static 329 // static
456 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
457 const PrefetchData& data) {
458 if (data.primary_key.length() > kMaxStringLength)
459 return false;
460
461 for (const ResourceData& resource : data.resources) {
462 if (resource.resource_url().length() > kMaxStringLength)
463 return false;
464 }
465 return true;
466 }
467
468 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
469 const RedirectData& data) {
470 if (data.primary_key().length() > kMaxStringLength)
471 return false;
472
473 for (const RedirectStat& redirect : data.redirect_endpoints()) {
474 if (redirect.url().length() > kMaxStringLength)
475 return false;
476 }
477 return true;
478 }
479
480 // static
481 float ResourcePrefetchPredictorTables::ComputeResourceScore( 330 float ResourcePrefetchPredictorTables::ComputeResourceScore(
482 const ResourceData& data) { 331 const ResourceData& data) {
483 // The ranking is done by considering, in this order: 332 // The ranking is done by considering, in this order:
484 // 1. Resource Priority 333 // 1. Resource Priority
485 // 2. Request resource type 334 // 2. Request resource type
486 // 3. Finally, the average position, giving a higher priotity to earlier 335 // 3. Finally, the average position, giving a higher priotity to earlier
487 // resources. 336 // resources.
488 337
489 int priority_multiplier; 338 int priority_multiplier;
490 switch (data.priority()) { 339 switch (data.priority()) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 } 379 }
531 380
532 // static 381 // static
533 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( 382 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated(
534 sql::Connection* db) { 383 sql::Connection* db) {
535 int version = GetDatabaseVersion(db); 384 int version = GetDatabaseVersion(db);
536 bool success = true; 385 bool success = true;
537 // Too new is also a problem. 386 // Too new is also a problem.
538 bool incompatible_version = version != kDatabaseVersion; 387 bool incompatible_version = version != kDatabaseVersion;
539 388
389 // These are deprecated tables but they still have to be removed if present.
390 const char kUrlMetadataTableName[] =
391 "resource_prefetch_predictor_url_metadata";
392 const char kHostMetadataTableName[] =
393 "resource_prefetch_predictor_host_metadata";
394
540 if (incompatible_version) { 395 if (incompatible_version) {
541 for (const char* table_name : 396 for (const char* table_name :
542 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName, 397 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName,
543 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName, 398 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName,
544 kHostMetadataTableName}) { 399 kHostMetadataTableName}) {
545 success = 400 success =
546 success && 401 success &&
547 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name) 402 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name)
548 .c_str()); 403 .c_str());
549 } 404 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 if (CantAccessDatabase()) 446 if (CantAccessDatabase())
592 return; 447 return;
593 448
594 // Database initialization is all-or-nothing. 449 // Database initialization is all-or-nothing.
595 sql::Connection* db = DB(); 450 sql::Connection* db = DB();
596 sql::Transaction transaction{db}; 451 sql::Transaction transaction{db};
597 bool success = transaction.Begin(); 452 bool success = transaction.Begin();
598 453
599 success = success && DropTablesIfOutdated(db); 454 success = success && DropTablesIfOutdated(db);
600 455
601 success = 456 for (const char* table_name :
602 success && 457 {kUrlResourceTableName, kHostResourceTableName, kUrlRedirectTableName,
603 (db->DoesTableExist(kUrlResourceTableName) || 458 kHostRedirectTableName}) {
604 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, 459 success = success &&
605 kUrlResourceTableName) 460 (db->DoesTableExist(table_name) ||
606 .c_str())) && 461 db->Execute(base::StringPrintf(
607 (db->DoesTableExist(kUrlMetadataTableName) || 462 kCreateProtoTableStatementTemplate, table_name)
608 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, 463 .c_str()));
609 kUrlMetadataTableName) 464 }
610 .c_str())) &&
611 (db->DoesTableExist(kUrlRedirectTableName) ||
612 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
613 kUrlRedirectTableName)
614 .c_str())) &&
615 (db->DoesTableExist(kHostResourceTableName) ||
616 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
617 kHostResourceTableName)
618 .c_str())) &&
619 (db->DoesTableExist(kHostMetadataTableName) ||
620 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
621 kHostMetadataTableName)
622 .c_str())) &&
623 (db->DoesTableExist(kHostRedirectTableName) ||
624 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
625 kHostRedirectTableName)
626 .c_str()));
627 465
628 if (success) 466 if (success)
629 success = transaction.Commit(); 467 success = transaction.Commit();
630 else 468 else
631 transaction.Rollback(); 469 transaction.Rollback();
632 470
633 if (!success) 471 if (!success)
634 ResetDB(); 472 ResetDB();
635 } 473 }
636 474
(...skipping 16 matching lines...) Expand all
653 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount", 491 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount",
654 statement.ColumnInt(0)); 492 statement.ColumnInt(0));
655 } 493 }
656 494
657 std::unique_ptr<Statement> 495 std::unique_ptr<Statement>
658 ResourcePrefetchPredictorTables::GetTableUpdateStatement( 496 ResourcePrefetchPredictorTables::GetTableUpdateStatement(
659 PrefetchKeyType key_type, 497 PrefetchKeyType key_type,
660 PrefetchDataType data_type, 498 PrefetchDataType data_type,
661 TableOperationType op_type) { 499 TableOperationType op_type) {
662 sql::StatementID id(__FILE__, key_type | (static_cast<int>(data_type) << 1) | 500 sql::StatementID id(__FILE__, key_type | (static_cast<int>(data_type) << 1) |
663 (static_cast<int>(op_type) << 3)); 501 (static_cast<int>(op_type) << 2));
664 const char* statement_template = 502 const char* statement_template = (op_type == TableOperationType::REMOVE
665 GetTableUpdateStatementTemplate(op_type, data_type); 503 ? kDeleteProtoTableStatementTemplate
666 const char* table_name = 504 : kInsertProtoTableStatementTemplate);
667 GetTableUpdateStatementTableName(key_type, data_type); 505 const char* table_name = GetTableName(key_type, data_type);
668 return base::MakeUnique<Statement>(DB()->GetCachedStatement( 506 return base::MakeUnique<Statement>(DB()->GetCachedStatement(
669 id, base::StringPrintf(statement_template, table_name).c_str())); 507 id, base::StringPrintf(statement_template, table_name).c_str()));
670 } 508 }
671 509
672 // static 510 // static
673 const char* ResourcePrefetchPredictorTables::GetTableUpdateStatementTemplate( 511 const char* ResourcePrefetchPredictorTables::GetTableName(
674 TableOperationType op_type,
675 PrefetchDataType data_type) {
676 switch (op_type) {
677 case TableOperationType::REMOVE:
678 return kDeleteStatementTemplate;
679 case TableOperationType::INSERT:
680 switch (data_type) {
681 case PrefetchDataType::RESOURCE:
682 return kInsertResourceTableStatementTemplate;
683 case PrefetchDataType::REDIRECT:
684 return kInsertRedirectTableStatementTemplate;
685 case PrefetchDataType::METADATA:
686 return kInsertMetadataTableStatementTemplate;
687 }
688 }
689
690 NOTREACHED();
691 return nullptr;
692 }
693
694 // static
695 const char* ResourcePrefetchPredictorTables::GetTableUpdateStatementTableName(
696 PrefetchKeyType key_type, 512 PrefetchKeyType key_type,
697 PrefetchDataType data_type) { 513 PrefetchDataType data_type) {
698 DCHECK(key_type == PREFETCH_KEY_TYPE_URL ||
699 key_type == PREFETCH_KEY_TYPE_HOST);
700 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 514 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
701 switch (data_type) { 515 switch (data_type) {
702 case PrefetchDataType::RESOURCE: 516 case PrefetchDataType::RESOURCE:
703 return is_host ? kHostResourceTableName : kUrlResourceTableName; 517 return is_host ? kHostResourceTableName : kUrlResourceTableName;
704 case PrefetchDataType::REDIRECT: 518 case PrefetchDataType::REDIRECT:
705 return is_host ? kHostRedirectTableName : kUrlRedirectTableName; 519 return is_host ? kHostRedirectTableName : kUrlRedirectTableName;
706 case PrefetchDataType::METADATA:
707 return is_host ? kHostMetadataTableName : kUrlMetadataTableName;
708 } 520 }
709 521
710 NOTREACHED(); 522 NOTREACHED();
711 return nullptr; 523 return nullptr;
712 } 524 }
713 525
714 } // namespace predictors 526 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698