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

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

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

Powered by Google App Engine
This is Rietveld 408576698