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

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

Issue 2355273002: Redirect handling in the resource_prefetch_predictor. (Closed)
Patch Set: Minor changes Created 4 years, 3 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, "
Benoit L 2016/09/26 11:18:36 Would this be "initial_url" instead?
alexilin 2016/09/26 12:14:54 Yeah, but then we will have to have two different
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 DeleteResourceDataHelper(PREFETCH_KEY_TYPE_URL, urls);
241 if (!hosts.empty())
242 DeleteResourceDataHelper(PREFETCH_KEY_TYPE_HOST, hosts);
243 }
244
245 void ResourcePrefetchPredictorTables::DeleteSingleResourceDataPoint(
246 const std::string& key,
247 PrefetchKeyType key_type) {
248 DCHECK_CURRENTLY_ON(BrowserThread::DB);
249 if (CantAccessDatabase())
250 return;
251
252 DeleteResourceDataHelper(key_type, {key});
253 }
254
255 void ResourcePrefetchPredictorTables::DeleteRedirectData(
256 const std::vector<std::string>& urls,
257 const std::vector<std::string>& hosts) {
258 DCHECK_CURRENTLY_ON(BrowserThread::DB);
166 if (CantAccessDatabase()) 259 if (CantAccessDatabase())
167 return; 260 return;
168 261
169 DCHECK(!urls.empty() || !hosts.empty()); 262 DCHECK(!urls.empty() || !hosts.empty());
170 263
171 if (!urls.empty()) 264 if (!urls.empty())
172 DeleteDataHelper(PREFETCH_KEY_TYPE_URL, urls); 265 DeleteRedirectDataHelper(PREFETCH_KEY_TYPE_URL, urls);
173 if (!hosts.empty()) 266 if (!hosts.empty())
174 DeleteDataHelper(PREFETCH_KEY_TYPE_HOST, hosts); 267 DeleteRedirectDataHelper(PREFETCH_KEY_TYPE_HOST, hosts);
175 } 268 }
176 269
177 void ResourcePrefetchPredictorTables::DeleteSingleDataPoint( 270 void ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint(
178 const std::string& key, 271 const std::string& key,
179 PrefetchKeyType key_type) { 272 PrefetchKeyType key_type) {
180 DCHECK_CURRENTLY_ON(BrowserThread::DB); 273 DCHECK_CURRENTLY_ON(BrowserThread::DB);
181 if (CantAccessDatabase()) 274 if (CantAccessDatabase())
182 return; 275 return;
183 276
184 DeleteDataHelper(key_type, std::vector<std::string>(1, key)); 277 DeleteRedirectDataHelper(key_type, {key});
185 } 278 }
186 279
187 void ResourcePrefetchPredictorTables::DeleteAllData() { 280 void ResourcePrefetchPredictorTables::DeleteAllData() {
188 if (CantAccessDatabase()) 281 if (CantAccessDatabase())
189 return; 282 return;
190 283
191 Statement deleter; 284 Statement deleter;
192 for (const char* table_name : 285 for (const char* table_name :
193 {kUrlResourceTableName, kUrlMetadataTableName, kHostResourceTableName, 286 {kUrlResourceTableName, kUrlMetadataTableName, kUrlRedirectTableName,
194 kHostMetadataTableName}) { 287 kHostResourceTableName, kHostMetadataTableName,
288 kHostRedirectTableName}) {
195 deleter.Assign(DB()->GetUniqueStatement( 289 deleter.Assign(DB()->GetUniqueStatement(
196 base::StringPrintf("DELETE FROM %s", table_name).c_str())); 290 base::StringPrintf("DELETE FROM %s", table_name).c_str()));
197 deleter.Run(); 291 deleter.Run();
198 } 292 }
199 } 293 }
200 294
201 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() 295 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables()
202 : PredictorTableBase() { 296 : PredictorTableBase() {
203 } 297 }
204 298
205 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() { 299 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {
206 } 300 }
207 301
208 void ResourcePrefetchPredictorTables::GetAllDataHelper( 302 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper(
209 PrefetchKeyType key_type, 303 PrefetchKeyType key_type,
210 PrefetchDataMap* data_map, 304 PrefetchDataMap* data_map,
211 std::vector<std::string>* to_delete) { 305 std::vector<std::string>* to_delete) {
212 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 306 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
213 307
214 // Read the resources table and organize it per primary key. 308 // Read the resources table and organize it per primary key.
215 const char* resource_table_name = is_host ? kHostResourceTableName : 309 const char* resource_table_name = is_host ? kHostResourceTableName :
216 kUrlResourceTableName; 310 kUrlResourceTableName;
217 Statement resource_reader(DB()->GetUniqueStatement( 311 Statement resource_reader(DB()->GetUniqueStatement(
218 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str())); 312 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str()));
219 313
220 ResourceData resource; 314 ResourceData resource;
221 std::string primary_key; 315 std::string primary_key;
222 while (StepAndInitializeResourceData(&resource_reader, &resource, 316 while (StepAndInitializeResourceData(&resource_reader, &resource,
223 &primary_key)) { 317 &primary_key)) {
224 PrefetchDataMap::iterator it = data_map->find(primary_key); 318 PrefetchDataMap::iterator it = data_map->find(primary_key);
225 if (it == data_map->end()) { 319 if (it == data_map->end()) {
226 it = data_map->insert(std::make_pair( 320 it = data_map->insert(std::make_pair(
227 primary_key, PrefetchData(key_type, primary_key))).first; 321 primary_key, PrefetchData(key_type, primary_key))).first;
228 } 322 }
229 it->second.resources.push_back(resource); 323 it->second.resources.push_back(resource);
230 } 324 }
231 325
232 // Sort each of the resource row vectors by score. 326 // Sort each of the resource row vectors by score.
233 for (auto& kv : *data_map) 327 for (auto& kv : *data_map)
234 SortResources(&(kv.second.resources)); 328 SortResources(&(kv.second.resources));
235 329
236 // Read the metadata and keep track of entries that have metadata, but no 330 // Read the metadata and keep track of entries that have metadata, but no
237 // resource entries, so they can be deleted. 331 // resource entries, so they can be deleted.
238 const char* metadata_table_name = is_host ? kHostMetadataTableName : 332 const char* metadata_table_name =
239 kUrlMetadataTableName; 333 is_host ? kHostMetadataTableName : kUrlMetadataTableName;
240 Statement metadata_reader(DB()->GetUniqueStatement( 334 Statement metadata_reader(DB()->GetUniqueStatement(
241 base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str())); 335 base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str()));
242 336
243 while (metadata_reader.Step()) { 337 while (metadata_reader.Step()) {
244 std::string primary_key = metadata_reader.ColumnString(0); 338 std::string primary_key = metadata_reader.ColumnString(0);
245 339
246 PrefetchDataMap::iterator it = data_map->find(primary_key); 340 PrefetchDataMap::iterator it = data_map->find(primary_key);
247 if (it != data_map->end()) { 341 if (it != data_map->end()) {
248 int64_t last_visit = metadata_reader.ColumnInt64(1); 342 int64_t last_visit = metadata_reader.ColumnInt64(1);
249 it->second.last_visit = base::Time::FromInternalValue(last_visit); 343 it->second.last_visit = base::Time::FromInternalValue(last_visit);
250 } else { 344 } else {
251 to_delete->push_back(primary_key); 345 to_delete->push_back(primary_key);
252 } 346 }
253 } 347 }
254 } 348 }
255 349
256 bool ResourcePrefetchPredictorTables::UpdateDataHelper( 350 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper(
351 PrefetchKeyType key_type,
352 RedirectDataMap* redirect_map) {
353 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
354
355 const char* redirect_table_name =
356 is_host ? kHostRedirectTableName : kUrlRedirectTableName;
357 Statement redirect_reader(DB()->GetUniqueStatement(
358 base::StringPrintf("SELECT * FROM %s", redirect_table_name).c_str()));
359
360 RedirectData data;
361 std::string primary_key;
362 while (StepAndInitializeRedirectData(&redirect_reader, &data, &primary_key)) {
363 auto result = redirect_map->insert(std::make_pair(primary_key, data));
364 DCHECK(result.second);
365 }
366 }
367
368 bool ResourcePrefetchPredictorTables::UpdateResourceDataHelper(
369 PrefetchKeyType key_type,
257 const PrefetchData& data) { 370 const PrefetchData& data) {
258 DCHECK(!data.primary_key.empty()); 371 DCHECK(!data.primary_key.empty());
259 372
260 if (!StringsAreSmallerThanDBLimit(data)) { 373 if (!StringsAreSmallerThanDBLimit(data)) {
261 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true); 374 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
262 return false; 375 return false;
263 } 376 }
264 377
378 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
379
265 // Delete the older data from both the tables. 380 // Delete the older data from both the tables.
266 std::unique_ptr<Statement> deleter(data.is_host() 381 std::unique_ptr<Statement> deleter(is_host ? GetHostResourceDeleteStatement()
267 ? GetHostResourceDeleteStatement() 382 : GetUrlResourceDeleteStatement());
268 : GetUrlResourceDeleteStatement());
269 deleter->BindString(0, data.primary_key); 383 deleter->BindString(0, data.primary_key);
270 if (!deleter->Run()) 384 if (!deleter->Run())
271 return false; 385 return false;
272 386
273 deleter.reset(data.is_host() ? GetHostMetadataDeleteStatement() : 387 deleter.reset(data.is_host() ? GetHostMetadataDeleteStatement()
274 GetUrlMetadataDeleteStatement()); 388 : GetUrlMetadataDeleteStatement());
275 deleter->BindString(0, data.primary_key); 389 deleter->BindString(0, data.primary_key);
276 if (!deleter->Run()) 390 if (!deleter->Run())
277 return false; 391 return false;
278 392
279 // Add the new data to the tables. 393 // Add the new data to the tables.
280 for (const ResourceData& resource : data.resources) { 394 for (const ResourceData& resource : data.resources) {
281 std::unique_ptr<Statement> resource_inserter( 395 std::unique_ptr<Statement> resource_inserter(
282 data.is_host() ? GetHostResourceUpdateStatement() 396 is_host ? GetHostResourceUpdateStatement()
283 : GetUrlResourceUpdateStatement()); 397 : 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(
291 data.is_host() ? GetHostMetadataUpdateStatement() 405 is_host ? GetHostMetadataUpdateStatement()
292 : GetUrlMetadataUpdateStatement()); 406 : GetUrlMetadataUpdateStatement());
293 metadata_inserter->BindString(0, data.primary_key); 407 metadata_inserter->BindString(0, data.primary_key);
294 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue()); 408 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue());
295 if (!metadata_inserter->Run()) 409 if (!metadata_inserter->Run())
296 return false; 410 return false;
297 411
298 return true; 412 return true;
299 } 413 }
300 414
301 void ResourcePrefetchPredictorTables::DeleteDataHelper( 415 bool ResourcePrefetchPredictorTables::UpdateRedirectDataHelper(
416 PrefetchKeyType key_type,
417 const RedirectData& data) {
418 DCHECK(data.has_primary_key());
419
420 if (!StringsAreSmallerThanDBLimit(data)) {
421 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
422 return false;
423 }
424
425 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
426
427 // Delete the older data from the table.
428 std::unique_ptr<Statement> deleter(is_host ? GetHostRedirectDeleteStatement()
429 : GetUrlRedirectDeleteStatement());
430 deleter->BindString(0, data.primary_key());
431 if (!deleter->Run())
432 return false;
433
434 // Add the new data to the table.
435 std::unique_ptr<Statement> inserter(is_host
436 ? GetHostRedirectUpdateStatement()
437 : GetUrlRedirectUpdateStatement());
438 BindRedirectDataToStatement(data, inserter.get());
439 if (!inserter->Run())
440 return false;
441
442 return true;
443 }
444
445 void ResourcePrefetchPredictorTables::DeleteResourceDataHelper(
302 PrefetchKeyType key_type, 446 PrefetchKeyType key_type,
303 const std::vector<std::string>& keys) { 447 const std::vector<std::string>& keys) {
304 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 448 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
305 449
306 for (const std::string& key : keys) { 450 for (const std::string& key : keys) {
307 std::unique_ptr<Statement> deleter(is_host 451 std::unique_ptr<Statement> deleter(is_host
308 ? GetHostResourceDeleteStatement() 452 ? GetHostResourceDeleteStatement()
309 : GetUrlResourceDeleteStatement()); 453 : GetUrlResourceDeleteStatement());
310 deleter->BindString(0, key); 454 deleter->BindString(0, key);
311 deleter->Run(); 455 deleter->Run();
312 456
313 deleter.reset(is_host ? GetHostMetadataDeleteStatement() : 457 deleter.reset(is_host ? GetHostMetadataDeleteStatement()
314 GetUrlMetadataDeleteStatement()); 458 : GetUrlMetadataDeleteStatement());
315 deleter->BindString(0, key); 459 deleter->BindString(0, key);
316 deleter->Run(); 460 deleter->Run();
317 } 461 }
462 }
463
464 void ResourcePrefetchPredictorTables::DeleteRedirectDataHelper(
465 PrefetchKeyType key_type,
466 const std::vector<std::string>& keys) {
467 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
468
469 for (const std::string& key : keys) {
470 std::unique_ptr<Statement> deleter(is_host
471 ? GetHostRedirectDeleteStatement()
472 : GetUrlRedirectDeleteStatement());
473 deleter->BindString(0, key);
474 deleter->Run();
475 }
318 } 476 }
319 477
320 // static 478 // static
321 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit( 479 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
322 const PrefetchData& data) { 480 const PrefetchData& data) {
323 if (data.primary_key.length() > kMaxStringLength) 481 if (data.primary_key.length() > kMaxStringLength)
324 return false; 482 return false;
325 483
326 for (const ResourceData& resource : data.resources) { 484 for (const ResourceData& resource : data.resources) {
327 if (resource.resource_url().length() > kMaxStringLength) 485 if (resource.resource_url().length() > kMaxStringLength)
328 return false; 486 return false;
329 } 487 }
330 return true; 488 return true;
331 } 489 }
332 490
491 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
492 const RedirectData& data) {
493 if (data.primary_key().length() > kMaxStringLength)
494 return false;
495
496 for (const RedirectStat& redirect : data.redirects()) {
497 if (redirect.url().length() > kMaxStringLength)
498 return false;
499 }
500 return true;
501 }
502
333 // static 503 // static
334 float ResourcePrefetchPredictorTables::ComputeScore(const ResourceData& data) { 504 float ResourcePrefetchPredictorTables::ComputeResourceScore(
505 const ResourceData& data) {
335 // The score is calculated so that when the rows are sorted, stylesheets, 506 // 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 507 // scripts and fonts appear first, sorted by position(ascending) and then the
337 // rest of the resources sorted by position (ascending). 508 // rest of the resources sorted by position (ascending).
338 static const int kMaxResourcesPerType = 100; 509 static const int kMaxResourcesPerType = 100;
339 switch (data.resource_type()) { 510 switch (data.resource_type()) {
340 case ResourceData::RESOURCE_TYPE_STYLESHEET: 511 case ResourceData::RESOURCE_TYPE_STYLESHEET:
341 case ResourceData::RESOURCE_TYPE_SCRIPT: 512 case ResourceData::RESOURCE_TYPE_SCRIPT:
342 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE: 513 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE:
343 return (2 * kMaxResourcesPerType) - data.average_position(); 514 return (2 * kMaxResourcesPerType) - data.average_position();
344 515
345 case ResourceData::RESOURCE_TYPE_IMAGE: 516 case ResourceData::RESOURCE_TYPE_IMAGE:
346 default: 517 default:
347 return kMaxResourcesPerType - data.average_position(); 518 return kMaxResourcesPerType - data.average_position();
348 } 519 }
349 // TODO(lizeb): Take priority into account. 520 // TODO(lizeb): Take priority into account.
350 } 521 }
351 522
352 // static 523 // static
524 float ResourcePrefetchPredictorTables::ComputeRedirectScore(
525 const RedirectStat& data) {
526 // TODO(alexilin): Invent some scoring.
527 return 0.0;
528 }
529
530 // static
353 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( 531 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated(
354 sql::Connection* db) { 532 sql::Connection* db) {
355 int version = GetDatabaseVersion(db); 533 int version = GetDatabaseVersion(db);
356 bool success = true; 534 bool success = true;
357 // Too new is also a problem. 535 // Too new is also a problem.
358 bool incompatible_version = version != kDatabaseVersion; 536 bool incompatible_version = version != kDatabaseVersion;
359 537
360 if (incompatible_version) { 538 if (incompatible_version) {
361 for (const char* table_name : 539 for (const char* table_name :
362 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName, 540 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName,
363 kUrlMetadataTableName, kHostMetadataTableName}) { 541 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName,
542 kHostMetadataTableName}) {
364 success = 543 success =
365 success && 544 success &&
366 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name) 545 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name)
367 .c_str()); 546 .c_str());
368 } 547 }
369 } 548 }
370 549
371 if (incompatible_version) { 550 if (incompatible_version) {
372 success = 551 success =
373 success && 552 success &&
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 success = 599 success =
421 success && 600 success &&
422 (db->DoesTableExist(kUrlResourceTableName) || 601 (db->DoesTableExist(kUrlResourceTableName) ||
423 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, 602 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
424 kUrlResourceTableName) 603 kUrlResourceTableName)
425 .c_str())) && 604 .c_str())) &&
426 (db->DoesTableExist(kUrlMetadataTableName) || 605 (db->DoesTableExist(kUrlMetadataTableName) ||
427 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, 606 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
428 kUrlMetadataTableName) 607 kUrlMetadataTableName)
429 .c_str())) && 608 .c_str())) &&
609 (db->DoesTableExist(kUrlRedirectTableName) ||
610 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
611 kUrlRedirectTableName)
612 .c_str())) &&
430 (db->DoesTableExist(kHostResourceTableName) || 613 (db->DoesTableExist(kHostResourceTableName) ||
431 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, 614 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
432 kHostResourceTableName) 615 kHostResourceTableName)
433 .c_str())) && 616 .c_str())) &&
434 (db->DoesTableExist(kHostMetadataTableName) || 617 (db->DoesTableExist(kHostMetadataTableName) ||
435 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, 618 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
436 kHostMetadataTableName) 619 kHostMetadataTableName)
620 .c_str())) &&
621 (db->DoesTableExist(kHostRedirectTableName) ||
622 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
623 kHostRedirectTableName)
437 .c_str())); 624 .c_str()));
438 625
439 if (success) 626 if (success)
440 success = transaction.Commit(); 627 success = transaction.Commit();
441 else 628 else
442 transaction.Rollback(); 629 transaction.Rollback();
443 630
444 if (!success) 631 if (!success)
445 ResetDB(); 632 ResetDB();
446 } 633 }
447 634
448 void ResourcePrefetchPredictorTables::LogDatabaseStats() { 635 void ResourcePrefetchPredictorTables::LogDatabaseStats() {
449 DCHECK_CURRENTLY_ON(BrowserThread::DB); 636 DCHECK_CURRENTLY_ON(BrowserThread::DB);
450 if (CantAccessDatabase()) 637 if (CantAccessDatabase())
451 return; 638 return;
452 639
453 Statement statement(DB()->GetUniqueStatement( 640 Statement statement(DB()->GetUniqueStatement(
454 base::StringPrintf("SELECT count(*) FROM %s", 641 base::StringPrintf("SELECT count(*) FROM %s",
455 kUrlResourceTableName).c_str())); 642 kUrlResourceTableName).c_str()));
456 if (statement.Step()) 643 if (statement.Step())
457 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableRowCount", 644 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableRowCount",
458 statement.ColumnInt(0)); 645 statement.ColumnInt(0));
459 646
460 statement.Assign(DB()->GetUniqueStatement( 647 statement.Assign(DB()->GetUniqueStatement(
461 base::StringPrintf("SELECT count(*) FROM %s", 648 base::StringPrintf("SELECT count(*) FROM %s",
462 kHostResourceTableName).c_str())); 649 kHostResourceTableName).c_str()));
463 if (statement.Step()) 650 if (statement.Step())
464 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount", 651 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount",
465 statement.ColumnInt(0)); 652 statement.ColumnInt(0));
653
654 statement.Assign(DB()->GetUniqueStatement(
655 base::StringPrintf("SELECT count(*) FROM %s", kUrlRedirectTableName)
656 .c_str()));
657 if (statement.Step())
658 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlRedirectTableRowCount",
659 statement.ColumnInt(0));
660
661 statement.Assign(DB()->GetUniqueStatement(
662 base::StringPrintf("SELECT count(*) FROM %s", kHostRedirectTableName)
663 .c_str()));
664 if (statement.Step())
665 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostRedirectTableRowCount",
666 statement.ColumnInt(0));
466 } 667 }
467 668
468 Statement* 669 Statement*
469 ResourcePrefetchPredictorTables::GetUrlResourceDeleteStatement() { 670 ResourcePrefetchPredictorTables::GetUrlResourceDeleteStatement() {
470 return new Statement(DB()->GetCachedStatement( 671 return new Statement(DB()->GetCachedStatement(
471 SQL_FROM_HERE, 672 SQL_FROM_HERE,
472 base::StringPrintf(kDeleteStatementTemplate, kUrlResourceTableName) 673 base::StringPrintf(kDeleteStatementTemplate, kUrlResourceTableName)
473 .c_str())); 674 .c_str()));
474 } 675 }
475 676
476 Statement* 677 Statement*
477 ResourcePrefetchPredictorTables::GetUrlResourceUpdateStatement() { 678 ResourcePrefetchPredictorTables::GetUrlResourceUpdateStatement() {
478 return new Statement(DB()->GetCachedStatement( 679 return new Statement(DB()->GetCachedStatement(
479 SQL_FROM_HERE, base::StringPrintf(kInsertResourceTableStatementTemplate, 680 SQL_FROM_HERE, base::StringPrintf(kInsertResourceTableStatementTemplate,
480 kUrlResourceTableName) 681 kUrlResourceTableName)
481 .c_str())); 682 .c_str()));
482 } 683 }
483 684
484 Statement* 685 Statement* ResourcePrefetchPredictorTables::GetUrlMetadataDeleteStatement() {
485 ResourcePrefetchPredictorTables::GetUrlMetadataDeleteStatement() {
486 return new Statement(DB()->GetCachedStatement( 686 return new Statement(DB()->GetCachedStatement(
487 SQL_FROM_HERE, 687 SQL_FROM_HERE,
488 base::StringPrintf(kDeleteStatementTemplate, kUrlMetadataTableName) 688 base::StringPrintf(kDeleteStatementTemplate, kUrlMetadataTableName)
489 .c_str())); 689 .c_str()));
490 } 690 }
491 691
492 Statement* 692 Statement* ResourcePrefetchPredictorTables::GetUrlMetadataUpdateStatement() {
493 ResourcePrefetchPredictorTables::GetUrlMetadataUpdateStatement() {
494 return new Statement(DB()->GetCachedStatement( 693 return new Statement(DB()->GetCachedStatement(
495 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, 694 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate,
496 kUrlMetadataTableName) 695 kUrlMetadataTableName)
497 .c_str())); 696 .c_str()));
498 } 697 }
499 698
699 Statement* ResourcePrefetchPredictorTables::GetUrlRedirectDeleteStatement() {
700 return new Statement(DB()->GetCachedStatement(
701 SQL_FROM_HERE,
702 base::StringPrintf(kDeleteStatementTemplate, kUrlRedirectTableName)
703 .c_str()));
704 }
705
706 Statement* ResourcePrefetchPredictorTables::GetUrlRedirectUpdateStatement() {
707 return new Statement(DB()->GetCachedStatement(
708 SQL_FROM_HERE, base::StringPrintf(kInsertRedirectTableStatementTemplate,
709 kUrlRedirectTableName)
710 .c_str()));
711 }
712
500 Statement* 713 Statement*
501 ResourcePrefetchPredictorTables::GetHostResourceDeleteStatement() { 714 ResourcePrefetchPredictorTables::GetHostResourceDeleteStatement() {
502 return new Statement(DB()->GetCachedStatement( 715 return new Statement(DB()->GetCachedStatement(
503 SQL_FROM_HERE, 716 SQL_FROM_HERE,
504 base::StringPrintf(kDeleteStatementTemplate, kHostResourceTableName) 717 base::StringPrintf(kDeleteStatementTemplate, kHostResourceTableName)
505 .c_str())); 718 .c_str()));
506 } 719 }
507 720
508 Statement* 721 Statement*
509 ResourcePrefetchPredictorTables::GetHostResourceUpdateStatement() { 722 ResourcePrefetchPredictorTables::GetHostResourceUpdateStatement() {
510 return new Statement(DB()->GetCachedStatement( 723 return new Statement(DB()->GetCachedStatement(
511 SQL_FROM_HERE, base::StringPrintf(kInsertResourceTableStatementTemplate, 724 SQL_FROM_HERE, base::StringPrintf(kInsertResourceTableStatementTemplate,
512 kHostResourceTableName) 725 kHostResourceTableName)
513 .c_str())); 726 .c_str()));
514 } 727 }
515 728
516 Statement* 729 Statement* ResourcePrefetchPredictorTables::GetHostMetadataDeleteStatement() {
517 ResourcePrefetchPredictorTables::GetHostMetadataDeleteStatement() {
518 return new Statement(DB()->GetCachedStatement( 730 return new Statement(DB()->GetCachedStatement(
519 SQL_FROM_HERE, 731 SQL_FROM_HERE,
520 base::StringPrintf(kDeleteStatementTemplate, kHostMetadataTableName) 732 base::StringPrintf(kDeleteStatementTemplate, kHostMetadataTableName)
521 .c_str())); 733 .c_str()));
522 } 734 }
523 735
524 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() { 736 Statement* ResourcePrefetchPredictorTables::GetHostMetadataUpdateStatement() {
525 return new Statement(DB()->GetCachedStatement( 737 return new Statement(DB()->GetCachedStatement(
526 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate, 738 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate,
527 kHostMetadataTableName) 739 kHostMetadataTableName)
528 .c_str())); 740 .c_str()));
529 } 741 }
530 742
743 Statement* ResourcePrefetchPredictorTables::GetHostRedirectDeleteStatement() {
744 return new Statement(DB()->GetCachedStatement(
745 SQL_FROM_HERE,
746 base::StringPrintf(kDeleteStatementTemplate, kHostRedirectTableName)
747 .c_str()));
748 }
749
750 Statement* ResourcePrefetchPredictorTables::GetHostRedirectUpdateStatement() {
751 return new Statement(DB()->GetCachedStatement(
752 SQL_FROM_HERE, base::StringPrintf(kInsertRedirectTableStatementTemplate,
753 kHostRedirectTableName)
754 .c_str()));
755 }
756
531 } // namespace predictors 757 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698