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

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

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

Powered by Google App Engine
This is Rietveld 408576698