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

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

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

Powered by Google App Engine
This is Rietveld 408576698