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

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

Issue 2355273002: Redirect handling in the resource_prefetch_predictor. (Closed)
Patch Set: Fix compilation complaints. 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, PrefetchDataType::RESOURCE, urls);
240 if (!hosts.empty())
241 DeleteDataHelper(PREFETCH_KEY_TYPE_HOST, PrefetchDataType::RESOURCE, hosts);
242 }
243
244 void ResourcePrefetchPredictorTables::DeleteSingleResourceDataPoint(
245 const std::string& key,
246 PrefetchKeyType key_type) {
247 DCHECK_CURRENTLY_ON(BrowserThread::DB);
248 if (CantAccessDatabase())
249 return;
250
251 DeleteDataHelper(key_type, PrefetchDataType::RESOURCE, {key});
252 }
253
254 void ResourcePrefetchPredictorTables::DeleteRedirectData(
255 const std::vector<std::string>& urls,
256 const std::vector<std::string>& hosts) {
257 DCHECK_CURRENTLY_ON(BrowserThread::DB);
166 if (CantAccessDatabase()) 258 if (CantAccessDatabase())
167 return; 259 return;
168 260
169 DCHECK(!urls.empty() || !hosts.empty()); 261 DCHECK(!urls.empty() || !hosts.empty());
170 262
171 if (!urls.empty()) 263 if (!urls.empty())
172 DeleteDataHelper(PREFETCH_KEY_TYPE_URL, urls); 264 DeleteDataHelper(PREFETCH_KEY_TYPE_URL, PrefetchDataType::REDIRECT, urls);
173 if (!hosts.empty()) 265 if (!hosts.empty())
174 DeleteDataHelper(PREFETCH_KEY_TYPE_HOST, hosts); 266 DeleteDataHelper(PREFETCH_KEY_TYPE_HOST, PrefetchDataType::REDIRECT, hosts);
175 } 267 }
176 268
177 void ResourcePrefetchPredictorTables::DeleteSingleDataPoint( 269 void ResourcePrefetchPredictorTables::DeleteSingleRedirectDataPoint(
178 const std::string& key, 270 const std::string& key,
179 PrefetchKeyType key_type) { 271 PrefetchKeyType key_type) {
180 DCHECK_CURRENTLY_ON(BrowserThread::DB); 272 DCHECK_CURRENTLY_ON(BrowserThread::DB);
181 if (CantAccessDatabase()) 273 if (CantAccessDatabase())
182 return; 274 return;
183 275
184 DeleteDataHelper(key_type, std::vector<std::string>(1, key)); 276 DeleteDataHelper(key_type, PrefetchDataType::REDIRECT, {key});
185 } 277 }
186 278
187 void ResourcePrefetchPredictorTables::DeleteAllData() { 279 void ResourcePrefetchPredictorTables::DeleteAllData() {
188 if (CantAccessDatabase()) 280 if (CantAccessDatabase())
189 return; 281 return;
190 282
191 Statement deleter; 283 Statement deleter;
192 for (const char* table_name : 284 for (const char* table_name :
193 {kUrlResourceTableName, kUrlMetadataTableName, kHostResourceTableName, 285 {kUrlResourceTableName, kUrlMetadataTableName, kUrlRedirectTableName,
194 kHostMetadataTableName}) { 286 kHostResourceTableName, kHostMetadataTableName,
287 kHostRedirectTableName}) {
195 deleter.Assign(DB()->GetUniqueStatement( 288 deleter.Assign(DB()->GetUniqueStatement(
196 base::StringPrintf("DELETE FROM %s", table_name).c_str())); 289 base::StringPrintf("DELETE FROM %s", table_name).c_str()));
197 deleter.Run(); 290 deleter.Run();
198 } 291 }
199 } 292 }
200 293
201 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables() 294 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables()
202 : PredictorTableBase() { 295 : PredictorTableBase() {
203 } 296 }
204 297
205 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() { 298 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {
206 } 299 }
207 300
208 void ResourcePrefetchPredictorTables::GetAllDataHelper( 301 void ResourcePrefetchPredictorTables::GetAllResourceDataHelper(
209 PrefetchKeyType key_type, 302 PrefetchKeyType key_type,
210 PrefetchDataMap* data_map, 303 PrefetchDataMap* data_map,
211 std::vector<std::string>* to_delete) { 304 std::vector<std::string>* to_delete) {
212 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 305 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
213 306
214 // Read the resources table and organize it per primary key. 307 // Read the resources table and organize it per primary key.
215 const char* resource_table_name = is_host ? kHostResourceTableName : 308 const char* resource_table_name = is_host ? kHostResourceTableName :
216 kUrlResourceTableName; 309 kUrlResourceTableName;
217 Statement resource_reader(DB()->GetUniqueStatement( 310 Statement resource_reader(DB()->GetUniqueStatement(
218 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str())); 311 base::StringPrintf("SELECT * FROM %s", resource_table_name).c_str()));
219 312
220 ResourceData resource; 313 ResourceData resource;
221 std::string primary_key; 314 std::string primary_key;
222 while (StepAndInitializeResourceData(&resource_reader, &resource, 315 while (StepAndInitializeResourceData(&resource_reader, &resource,
223 &primary_key)) { 316 &primary_key)) {
224 PrefetchDataMap::iterator it = data_map->find(primary_key); 317 PrefetchDataMap::iterator it = data_map->find(primary_key);
225 if (it == data_map->end()) { 318 if (it == data_map->end()) {
226 it = data_map->insert(std::make_pair( 319 it = data_map->insert(std::make_pair(
227 primary_key, PrefetchData(key_type, primary_key))).first; 320 primary_key, PrefetchData(key_type, primary_key))).first;
228 } 321 }
229 it->second.resources.push_back(resource); 322 it->second.resources.push_back(resource);
230 } 323 }
231 324
232 // Sort each of the resource row vectors by score. 325 // Sort each of the resource row vectors by score.
233 for (auto& kv : *data_map) 326 for (auto& kv : *data_map)
234 SortResources(&(kv.second.resources)); 327 SortResources(&(kv.second.resources));
235 328
236 // Read the metadata and keep track of entries that have metadata, but no 329 // Read the metadata and keep track of entries that have metadata, but no
237 // resource entries, so they can be deleted. 330 // resource entries, so they can be deleted.
238 const char* metadata_table_name = is_host ? kHostMetadataTableName : 331 const char* metadata_table_name =
239 kUrlMetadataTableName; 332 is_host ? kHostMetadataTableName : kUrlMetadataTableName;
240 Statement metadata_reader(DB()->GetUniqueStatement( 333 Statement metadata_reader(DB()->GetUniqueStatement(
241 base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str())); 334 base::StringPrintf("SELECT * FROM %s", metadata_table_name).c_str()));
242 335
243 while (metadata_reader.Step()) { 336 while (metadata_reader.Step()) {
244 std::string primary_key = metadata_reader.ColumnString(0); 337 std::string primary_key = metadata_reader.ColumnString(0);
245 338
246 PrefetchDataMap::iterator it = data_map->find(primary_key); 339 PrefetchDataMap::iterator it = data_map->find(primary_key);
247 if (it != data_map->end()) { 340 if (it != data_map->end()) {
248 int64_t last_visit = metadata_reader.ColumnInt64(1); 341 int64_t last_visit = metadata_reader.ColumnInt64(1);
249 it->second.last_visit = base::Time::FromInternalValue(last_visit); 342 it->second.last_visit = base::Time::FromInternalValue(last_visit);
250 } else { 343 } else {
251 to_delete->push_back(primary_key); 344 to_delete->push_back(primary_key);
252 } 345 }
253 } 346 }
254 } 347 }
255 348
256 bool ResourcePrefetchPredictorTables::UpdateDataHelper( 349 void ResourcePrefetchPredictorTables::GetAllRedirectDataHelper(
350 PrefetchKeyType key_type,
351 RedirectDataMap* redirect_map) {
352 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
353
354 const char* redirect_table_name =
355 is_host ? kHostRedirectTableName : kUrlRedirectTableName;
356 Statement redirect_reader(DB()->GetUniqueStatement(
357 base::StringPrintf("SELECT * FROM %s", redirect_table_name).c_str()));
358
359 RedirectData data;
360 std::string primary_key;
361 while (StepAndInitializeRedirectData(&redirect_reader, &data, &primary_key)) {
362 auto result = redirect_map->insert(std::make_pair(primary_key, data));
363 DCHECK(result.second);
364 }
365 }
366
367 bool ResourcePrefetchPredictorTables::UpdateResourceDataHelper(
368 PrefetchKeyType key_type,
257 const PrefetchData& data) { 369 const PrefetchData& data) {
258 DCHECK(!data.primary_key.empty()); 370 DCHECK(!data.primary_key.empty());
259 371
260 if (!StringsAreSmallerThanDBLimit(data)) { 372 if (!StringsAreSmallerThanDBLimit(data)) {
261 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true); 373 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
262 return false; 374 return false;
263 } 375 }
264 376
265 // Delete the older data from both the tables. 377 // Delete the older data from both the tables.
266 std::unique_ptr<Statement> deleter(data.is_host() 378 std::unique_ptr<Statement> deleter(GetTableUpdateStatement(
267 ? GetHostResourceDeleteStatement() 379 key_type, PrefetchDataType::RESOURCE, TableOperationType::REMOVE));
268 : GetUrlResourceDeleteStatement());
269 deleter->BindString(0, data.primary_key); 380 deleter->BindString(0, data.primary_key);
270 if (!deleter->Run()) 381 if (!deleter->Run())
271 return false; 382 return false;
272 383
273 deleter.reset(data.is_host() ? GetHostMetadataDeleteStatement() : 384 deleter = GetTableUpdateStatement(key_type, PrefetchDataType::METADATA,
274 GetUrlMetadataDeleteStatement()); 385 TableOperationType::REMOVE);
275 deleter->BindString(0, data.primary_key); 386 deleter->BindString(0, data.primary_key);
276 if (!deleter->Run()) 387 if (!deleter->Run())
277 return false; 388 return false;
278 389
279 // Add the new data to the tables. 390 // Add the new data to the tables.
280 for (const ResourceData& resource : data.resources) { 391 for (const ResourceData& resource : data.resources) {
281 std::unique_ptr<Statement> resource_inserter( 392 std::unique_ptr<Statement> resource_inserter(GetTableUpdateStatement(
282 data.is_host() ? GetHostResourceUpdateStatement() 393 key_type, PrefetchDataType::RESOURCE, TableOperationType::INSERT));
283 : GetUrlResourceUpdateStatement());
284 BindResourceDataToStatement(resource, data.primary_key, 394 BindResourceDataToStatement(resource, data.primary_key,
285 resource_inserter.get()); 395 resource_inserter.get());
286 if (!resource_inserter->Run()) 396 if (!resource_inserter->Run())
287 return false; 397 return false;
288 } 398 }
289 399
290 std::unique_ptr<Statement> metadata_inserter( 400 std::unique_ptr<Statement> metadata_inserter(GetTableUpdateStatement(
291 data.is_host() ? GetHostMetadataUpdateStatement() 401 key_type, PrefetchDataType::METADATA, TableOperationType::INSERT));
292 : GetUrlMetadataUpdateStatement());
293 metadata_inserter->BindString(0, data.primary_key); 402 metadata_inserter->BindString(0, data.primary_key);
294 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue()); 403 metadata_inserter->BindInt64(1, data.last_visit.ToInternalValue());
295 if (!metadata_inserter->Run()) 404 return metadata_inserter->Run();
405 }
406
407 bool ResourcePrefetchPredictorTables::UpdateRedirectDataHelper(
408 PrefetchKeyType key_type,
409 const RedirectData& data) {
410 DCHECK(data.has_primary_key());
411
412 if (!StringsAreSmallerThanDBLimit(data)) {
413 UMA_HISTOGRAM_BOOLEAN("ResourcePrefetchPredictor.DbStringTooLong", true);
414 return false;
415 }
416
417 // Delete the older data from the table.
418 std::unique_ptr<Statement> deleter(GetTableUpdateStatement(
419 key_type, PrefetchDataType::REDIRECT, TableOperationType::REMOVE));
420 deleter->BindString(0, data.primary_key());
421 if (!deleter->Run())
296 return false; 422 return false;
297 423
298 return true; 424 // Add the new data to the table.
425 std::unique_ptr<Statement> inserter(GetTableUpdateStatement(
426 key_type, PrefetchDataType::REDIRECT, TableOperationType::INSERT));
427 BindRedirectDataToStatement(data, inserter.get());
428 return inserter->Run();
299 } 429 }
300 430
301 void ResourcePrefetchPredictorTables::DeleteDataHelper( 431 void ResourcePrefetchPredictorTables::DeleteDataHelper(
302 PrefetchKeyType key_type, 432 PrefetchKeyType key_type,
433 PrefetchDataType data_type,
303 const std::vector<std::string>& keys) { 434 const std::vector<std::string>& keys) {
304 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST; 435 bool is_resource = data_type == PrefetchDataType::RESOURCE;
305 436
306 for (const std::string& key : keys) { 437 for (const std::string& key : keys) {
307 std::unique_ptr<Statement> deleter(is_host 438 std::unique_ptr<Statement> deleter(GetTableUpdateStatement(
308 ? GetHostResourceDeleteStatement() 439 key_type, data_type, TableOperationType::REMOVE));
309 : GetUrlResourceDeleteStatement());
310 deleter->BindString(0, key); 440 deleter->BindString(0, key);
311 deleter->Run(); 441 deleter->Run();
312 442
313 deleter.reset(is_host ? GetHostMetadataDeleteStatement() : 443 if (is_resource) {
314 GetUrlMetadataDeleteStatement()); 444 // Delete corresponding resource metadata as well.
315 deleter->BindString(0, key); 445 deleter = GetTableUpdateStatement(key_type, PrefetchDataType::METADATA,
316 deleter->Run(); 446 TableOperationType::REMOVE);
447 deleter->BindString(0, key);
448 deleter->Run();
449 }
317 } 450 }
318 } 451 }
319 452
320 // static 453 // static
321 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit( 454 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
322 const PrefetchData& data) { 455 const PrefetchData& data) {
323 if (data.primary_key.length() > kMaxStringLength) 456 if (data.primary_key.length() > kMaxStringLength)
324 return false; 457 return false;
325 458
326 for (const ResourceData& resource : data.resources) { 459 for (const ResourceData& resource : data.resources) {
327 if (resource.resource_url().length() > kMaxStringLength) 460 if (resource.resource_url().length() > kMaxStringLength)
328 return false; 461 return false;
329 } 462 }
330 return true; 463 return true;
331 } 464 }
332 465
466 bool ResourcePrefetchPredictorTables::StringsAreSmallerThanDBLimit(
467 const RedirectData& data) {
468 if (data.primary_key().length() > kMaxStringLength)
469 return false;
470
471 for (const RedirectStat& redirect : data.redirect_endpoints()) {
472 if (redirect.url().length() > kMaxStringLength)
473 return false;
474 }
475 return true;
476 }
477
333 // static 478 // static
334 float ResourcePrefetchPredictorTables::ComputeScore(const ResourceData& data) { 479 float ResourcePrefetchPredictorTables::ComputeResourceScore(
480 const ResourceData& data) {
335 // The score is calculated so that when the rows are sorted, stylesheets, 481 // 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 482 // scripts and fonts appear first, sorted by position(ascending) and then the
337 // rest of the resources sorted by position (ascending). 483 // rest of the resources sorted by position (ascending).
338 static const int kMaxResourcesPerType = 100; 484 static const int kMaxResourcesPerType = 100;
339 switch (data.resource_type()) { 485 switch (data.resource_type()) {
340 case ResourceData::RESOURCE_TYPE_STYLESHEET: 486 case ResourceData::RESOURCE_TYPE_STYLESHEET:
341 case ResourceData::RESOURCE_TYPE_SCRIPT: 487 case ResourceData::RESOURCE_TYPE_SCRIPT:
342 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE: 488 case ResourceData::RESOURCE_TYPE_FONT_RESOURCE:
343 return (2 * kMaxResourcesPerType) - data.average_position(); 489 return (2 * kMaxResourcesPerType) - data.average_position();
344 490
345 case ResourceData::RESOURCE_TYPE_IMAGE: 491 case ResourceData::RESOURCE_TYPE_IMAGE:
346 default: 492 default:
347 return kMaxResourcesPerType - data.average_position(); 493 return kMaxResourcesPerType - data.average_position();
348 } 494 }
349 // TODO(lizeb): Take priority into account. 495 // TODO(lizeb): Take priority into account.
350 } 496 }
351 497
352 // static 498 // static
499 float ResourcePrefetchPredictorTables::ComputeRedirectScore(
500 const RedirectStat& data) {
501 // TODO(alexilin): Invent some scoring.
502 return 0.0;
503 }
504
505 // static
353 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated( 506 bool ResourcePrefetchPredictorTables::DropTablesIfOutdated(
354 sql::Connection* db) { 507 sql::Connection* db) {
355 int version = GetDatabaseVersion(db); 508 int version = GetDatabaseVersion(db);
356 bool success = true; 509 bool success = true;
357 // Too new is also a problem. 510 // Too new is also a problem.
358 bool incompatible_version = version != kDatabaseVersion; 511 bool incompatible_version = version != kDatabaseVersion;
359 512
360 if (incompatible_version) { 513 if (incompatible_version) {
361 for (const char* table_name : 514 for (const char* table_name :
362 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName, 515 {kMetadataTableName, kUrlResourceTableName, kHostResourceTableName,
363 kUrlMetadataTableName, kHostMetadataTableName}) { 516 kUrlRedirectTableName, kHostRedirectTableName, kUrlMetadataTableName,
517 kHostMetadataTableName}) {
364 success = 518 success =
365 success && 519 success &&
366 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name) 520 db->Execute(base::StringPrintf("DROP TABLE IF EXISTS %s", table_name)
367 .c_str()); 521 .c_str());
368 } 522 }
369 } 523 }
370 524
371 if (incompatible_version) { 525 if (incompatible_version) {
372 success = 526 success =
373 success && 527 success &&
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 success = 574 success =
421 success && 575 success &&
422 (db->DoesTableExist(kUrlResourceTableName) || 576 (db->DoesTableExist(kUrlResourceTableName) ||
423 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, 577 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
424 kUrlResourceTableName) 578 kUrlResourceTableName)
425 .c_str())) && 579 .c_str())) &&
426 (db->DoesTableExist(kUrlMetadataTableName) || 580 (db->DoesTableExist(kUrlMetadataTableName) ||
427 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, 581 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
428 kUrlMetadataTableName) 582 kUrlMetadataTableName)
429 .c_str())) && 583 .c_str())) &&
584 (db->DoesTableExist(kUrlRedirectTableName) ||
585 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
586 kUrlRedirectTableName)
587 .c_str())) &&
430 (db->DoesTableExist(kHostResourceTableName) || 588 (db->DoesTableExist(kHostResourceTableName) ||
431 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate, 589 db->Execute(base::StringPrintf(kCreateResourceTableStatementTemplate,
432 kHostResourceTableName) 590 kHostResourceTableName)
433 .c_str())) && 591 .c_str())) &&
434 (db->DoesTableExist(kHostMetadataTableName) || 592 (db->DoesTableExist(kHostMetadataTableName) ||
435 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate, 593 db->Execute(base::StringPrintf(kCreateMetadataTableStatementTemplate,
436 kHostMetadataTableName) 594 kHostMetadataTableName)
595 .c_str())) &&
596 (db->DoesTableExist(kHostRedirectTableName) ||
597 db->Execute(base::StringPrintf(kCreateRedirectTableStatementTemplate,
598 kHostRedirectTableName)
437 .c_str())); 599 .c_str()));
438 600
439 if (success) 601 if (success)
440 success = transaction.Commit(); 602 success = transaction.Commit();
441 else 603 else
442 transaction.Rollback(); 604 transaction.Rollback();
443 605
444 if (!success) 606 if (!success)
445 ResetDB(); 607 ResetDB();
446 } 608 }
(...skipping 11 matching lines...) Expand all
458 statement.ColumnInt(0)); 620 statement.ColumnInt(0));
459 621
460 statement.Assign(DB()->GetUniqueStatement( 622 statement.Assign(DB()->GetUniqueStatement(
461 base::StringPrintf("SELECT count(*) FROM %s", 623 base::StringPrintf("SELECT count(*) FROM %s",
462 kHostResourceTableName).c_str())); 624 kHostResourceTableName).c_str()));
463 if (statement.Step()) 625 if (statement.Step())
464 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount", 626 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.HostTableRowCount",
465 statement.ColumnInt(0)); 627 statement.ColumnInt(0));
466 } 628 }
467 629
468 Statement* 630 std::unique_ptr<Statement>
469 ResourcePrefetchPredictorTables::GetUrlResourceDeleteStatement() { 631 ResourcePrefetchPredictorTables::GetTableUpdateStatement(
470 return new Statement(DB()->GetCachedStatement( 632 PrefetchKeyType key_type,
471 SQL_FROM_HERE, 633 PrefetchDataType data_type,
472 base::StringPrintf(kDeleteStatementTemplate, kUrlResourceTableName) 634 TableOperationType op_type) {
473 .c_str())); 635 sql::StatementID id(__FILE__, key_type | (static_cast<int>(data_type) << 1) |
636 (static_cast<int>(op_type) << 3));
637 const char* statement_template =
638 GetTableUpdateStatementTemplate(op_type, data_type);
639 const char* table_name =
640 GetTableUpdateStatementTableName(key_type, data_type);
641 return base::MakeUnique<Statement>(DB()->GetCachedStatement(
642 id, base::StringPrintf(statement_template, table_name).c_str()));
474 } 643 }
475 644
476 Statement* 645 // static
477 ResourcePrefetchPredictorTables::GetUrlResourceUpdateStatement() { 646 const char* ResourcePrefetchPredictorTables::GetTableUpdateStatementTemplate(
478 return new Statement(DB()->GetCachedStatement( 647 TableOperationType op_type,
479 SQL_FROM_HERE, base::StringPrintf(kInsertResourceTableStatementTemplate, 648 PrefetchDataType data_type) {
480 kUrlResourceTableName) 649 switch (op_type) {
481 .c_str())); 650 case TableOperationType::REMOVE:
651 return kDeleteStatementTemplate;
652 case TableOperationType::INSERT:
653 switch (data_type) {
654 case PrefetchDataType::RESOURCE:
655 return kInsertResourceTableStatementTemplate;
656 case PrefetchDataType::REDIRECT:
657 return kInsertRedirectTableStatementTemplate;
658 case PrefetchDataType::METADATA:
659 return kInsertMetadataTableStatementTemplate;
660 }
661 }
662
663 NOTREACHED();
664 return nullptr;
482 } 665 }
483 666
484 Statement* 667 // static
485 ResourcePrefetchPredictorTables::GetUrlMetadataDeleteStatement() { 668 const char* ResourcePrefetchPredictorTables::GetTableUpdateStatementTableName(
486 return new Statement(DB()->GetCachedStatement( 669 PrefetchKeyType key_type,
487 SQL_FROM_HERE, 670 PrefetchDataType data_type) {
488 base::StringPrintf(kDeleteStatementTemplate, kUrlMetadataTableName) 671 DCHECK(key_type == PREFETCH_KEY_TYPE_URL ||
489 .c_str())); 672 key_type == PREFETCH_KEY_TYPE_HOST);
490 } 673 bool is_host = key_type == PREFETCH_KEY_TYPE_HOST;
674 switch (data_type) {
675 case PrefetchDataType::RESOURCE:
676 return is_host ? kHostResourceTableName : kUrlResourceTableName;
677 case PrefetchDataType::REDIRECT:
678 return is_host ? kHostRedirectTableName : kUrlRedirectTableName;
679 case PrefetchDataType::METADATA:
680 return is_host ? kHostMetadataTableName : kUrlMetadataTableName;
681 }
491 682
492 Statement* 683 NOTREACHED();
493 ResourcePrefetchPredictorTables::GetUrlMetadataUpdateStatement() { 684 return nullptr;
494 return new Statement(DB()->GetCachedStatement(
495 SQL_FROM_HERE, base::StringPrintf(kInsertMetadataTableStatementTemplate,
496 kUrlMetadataTableName)
497 .c_str()));
498 }
499
500 Statement*
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 } 685 }
530 686
531 } // namespace predictors 687 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698