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

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

Issue 10416002: Seculative resource prefetching for URLs CL. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Addressing Will's comments and adding a unittest. Created 8 years, 6 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
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/stringprintf.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "sql/statement.h"
12
13 using content::BrowserThread;
14
15 namespace {
16
17 const char kResourcePredictorUrlTableName[] = "resource_prefetch_predictor_url";
18
19 // The maximum length allowed for strings in the database.
20 const size_t kMaxURLLength = 2048;
21
22 void BindUrlTableRowToStatement(
23 const predictors::ResourcePrefetchPredictorTables::UrlTableRow& row,
24 sql::Statement* statement) {
25 statement->BindString(0, row.main_frame_url.spec().substr(0, kMaxURLLength));
26 statement->BindString(1, row.resource_url.spec().substr(0, kMaxURLLength));
27 statement->BindInt(2, static_cast<int>(row.resource_type));
28 statement->BindInt(3, row.number_of_hits);
29 statement->BindInt(4, row.number_of_misses);
30 statement->BindInt(5, row.consecutive_misses);
31 statement->BindDouble(6, row.average_position);
32 }
33
34 bool StepAndInitializeUrlTableRow(
35 sql::Statement* statement,
36 predictors::ResourcePrefetchPredictorTables::UrlTableRow* row) {
37 if (!statement->Step())
38 return false;
39
40 row->main_frame_url = GURL(statement->ColumnString(0));
41 row->resource_url = GURL(statement->ColumnString(1));
42 row->resource_type = ResourceType::FromInt(statement->ColumnInt(2));
43 row->number_of_hits = statement->ColumnInt(3);
44 row->number_of_misses = statement->ColumnInt(4);
45 row->consecutive_misses = statement->ColumnInt(5);
46 row->average_position = statement->ColumnDouble(6);
47 return true;
48 }
49
50 } // namespace
51
52 namespace predictors {
53
54 ResourcePrefetchPredictorTables::UrlTableRow::UrlTableRow()
55 : resource_type(ResourceType::LAST_TYPE),
56 number_of_hits(0),
57 number_of_misses(0),
58 consecutive_misses(0),
59 average_position(0.0),
60 score(0.0) {
61 }
62
63 ResourcePrefetchPredictorTables::UrlTableRow::UrlTableRow(
64 const UrlTableRow& other)
65 : main_frame_url(other.main_frame_url),
66 resource_url(other.resource_url),
67 resource_type(other.resource_type),
68 number_of_hits(other.number_of_hits),
69 number_of_misses(other.number_of_misses),
70 consecutive_misses(other.consecutive_misses),
71 average_position(other.average_position),
72 score(other.score) {
73 }
74
75 void ResourcePrefetchPredictorTables::UrlTableRow::UpdateScore() {
76 // The score is calculated so that when the rows are sorted, the stylesheets
77 // and scripts appear first, sorted by position(ascending) and then the rest
78 // of the resources sorted by position(ascending).
79 static const int kMaxResourcesPerType = 100;
80 switch (resource_type) {
81 case ResourceType::STYLESHEET:
82 case ResourceType::SCRIPT:
83 score = (2 * kMaxResourcesPerType) - average_position;
84 break;
85
86 case ResourceType::IMAGE:
87 score = kMaxResourcesPerType - average_position;
88 break;
89
90 default:
91 score = kMaxResourcesPerType - average_position;
92 break;
93 }
94 }
95
96 bool ResourcePrefetchPredictorTables::UrlTableRowSorter::operator()(
97 const UrlTableRow& x,
98 const UrlTableRow& y) const {
99 return x.score > y.score;
100 }
101
102 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables()
103 : PredictorTableBase() {
104 }
105
106 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {
107 }
108
109 void ResourcePrefetchPredictorTables::GetAllRows(UrlTableRows* url_row_buffer) {
110 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
111 if (CantAccessDatabase())
112 return;
113
114 CHECK(url_row_buffer && url_row_buffer->empty());
115 sql::Statement url_statement(DB()->GetCachedStatement(SQL_FROM_HERE,
116 base::StringPrintf("SELECT * FROM %s",
117 kResourcePredictorUrlTableName).c_str()));
118
119 UrlTableRow url_row;
120 while (StepAndInitializeUrlTableRow(&url_statement, &url_row)) {
121 url_row.UpdateScore();
122 url_row_buffer->push_back(url_row);
123 }
124 }
125
126 void ResourcePrefetchPredictorTables::UpdateRowsForUrl(
127 const GURL& main_page_url,
128 const UrlTableRows& row_buffer) {
129 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
130 if (CantAccessDatabase())
131 return;
132
133 DB()->BeginTransaction();
134
135 sql::Statement delete_statement(DB()->GetCachedStatement(
136 SQL_FROM_HERE,
137 base::StringPrintf("DELETE FROM %s WHERE main_page_url=?",
138 kResourcePredictorUrlTableName).c_str()));
139 delete_statement.BindString(0, main_page_url.spec());
140 if (!delete_statement.Run()) {
141 DB()->RollbackTransaction();
142 return;
143 }
144
145 for (UrlTableRows::const_iterator it = row_buffer.begin();
146 it != row_buffer.end(); ++it) {
147 sql::Statement add_statement(
148 DB()->GetCachedStatement(
149 SQL_FROM_HERE,
150 base::StringPrintf(
151 "INSERT INTO %s "
152 "(main_page_url, resource_url, resource_type, number_of_hits, "
153 "number_of_misses, consecutive_misses, average_position) "
154 "VALUES (?,?,?,?,?,?,?)",
155 kResourcePredictorUrlTableName).c_str()));
156 BindUrlTableRowToStatement(*it, &add_statement);
157 if (!add_statement.Run()) {
158 DB()->RollbackTransaction();
159 return;
160 }
161 }
162
163 DB()->CommitTransaction();
164 }
165
166 void ResourcePrefetchPredictorTables::DeleteRowsForUrls(
167 const std::vector<GURL>& urls) {
168 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
169 if (CantAccessDatabase())
170 return;
171
172 // These do not need to be a transaction.
173 for (std::vector<GURL>::const_iterator it = urls.begin(); it != urls.end();
174 ++it) {
175 sql::Statement delete_statement(DB()->GetCachedStatement(
176 SQL_FROM_HERE,
177 base::StringPrintf("DELETE FROM %s WHERE main_page_url=?",
178 kResourcePredictorUrlTableName).c_str()));
179 delete_statement.BindString(0, it->spec());
180 delete_statement.Run();
181 }
182 }
183
184 void ResourcePrefetchPredictorTables::DeleteAllRows() {
185 if (CantAccessDatabase())
186 return;
187
188 sql::Statement statement(DB()->GetCachedStatement(
189 SQL_FROM_HERE,
190 base::StringPrintf("DELETE FROM %s",
191 kResourcePredictorUrlTableName).c_str()));
192 statement.Run();
193 }
194
195 void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() {
196 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
197 if (CantAccessDatabase())
198 return;
199
200 std::string url_table_creation_statement = base::StringPrintf(
201 "CREATE TABLE %s ( "
202 "main_page_url TEXT, "
203 "resource_url TEXT, "
204 "resource_type INTEGER, "
205 "number_of_hits INTEGER, "
206 "number_of_misses INTEGER, "
207 "consecutive_misses INTEGER, "
208 "average_position DOUBLE, "
209 "PRIMARY KEY(main_page_url, resource_url))",
210 kResourcePredictorUrlTableName);
211
212 if (!DB()->DoesTableExist(kResourcePredictorUrlTableName) &&
213 !DB()->Execute(url_table_creation_statement.c_str()))
214 ResetDB();
215 }
216
217 void ResourcePrefetchPredictorTables::LogDatabaseStats() {
218 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
219 if (CantAccessDatabase())
220 return;
221
222 sql::Statement url_statement(DB()->GetUniqueStatement(
223 base::StringPrintf("SELECT count(*) FROM %s",
224 kResourcePredictorUrlTableName).c_str()));
225 if (url_statement.Step())
226 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableRowCount",
227 url_statement.ColumnInt(0));
228 }
229
230 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698