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

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: Created 8 years, 7 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),
dominich 2012/05/21 16:16:53 warning: initializing a double with an int.
Shishir 2012/05/23 01:46:46 Done.
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() {
dominich 2012/05/21 16:16:53 Comment explaining the heuristic here. Also, might
Shishir 2012/05/23 01:46:46 Added comment. We might have additional field tria
76 static const int kMaxResourcesPerType = 100;
77 switch (resource_type_) {
78 case ResourceType::STYLESHEET:
79 case ResourceType::SCRIPT:
80 score_ = (2 * kMaxResourcesPerType) - average_position_;
81 break;
82
83 case ResourceType::IMAGE:
84 score_ = kMaxResourcesPerType - average_position_;
85 break;
86
87 default:
dominich 2012/05/21 16:16:53 What other resource types should be handled? Maybe
Shishir 2012/05/23 01:46:46 Sometimes we do not know the type of resource, eg
88 score_ = kMaxResourcesPerType - average_position_;
89 break;
90 }
91 }
92
93 bool ResourcePrefetchPredictorTables::UrlTableRowSorter::operator()(
94 const UrlTableRow& x,
95 const UrlTableRow& y) const {
96 return x.score_ > y.score_;
97 }
98
99 ResourcePrefetchPredictorTables::ResourcePrefetchPredictorTables()
100 : PredictorTableBase() {
101 }
102
103 ResourcePrefetchPredictorTables::~ResourcePrefetchPredictorTables() {
104 }
105
106 void ResourcePrefetchPredictorTables::CreateTableIfNonExistent() {
107 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
108 if (CantAccessDatabase())
109 return;
110
111 std::string url_table_creation_statement = base::StringPrintf(
112 "CREATE TABLE %s ( "
113 "main_page_url TEXT, "
114 "resource_url TEXT, "
115 "resource_type INTEGER, "
116 "number_of_hits INTEGER, "
117 "number_of_misses INTEGER, "
118 "consecutive_misses INTEGER, "
119 "average_position DOUBLE, "
120 "PRIMARY KEY(main_page_url, resource_url))",
121 kResourcePredictorUrlTableName);
122
123 if (!DB()->DoesTableExist(kResourcePredictorUrlTableName))
dominich 2012/05/21 16:16:53 add braces as the inner if has them.
Shishir 2012/05/23 01:46:46 Done.
124 if (!DB()->Execute(url_table_creation_statement.c_str())) {
125 ResetDB();
126 return;
127 }
128 }
129
130 void ResourcePrefetchPredictorTables::LogDatabaseStats() {
dominich 2012/05/21 16:16:53 Consider tracking the raw file size.
Shishir 2012/05/23 01:46:46 That happens in the PredictorDatabaseInternal.
131 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
132 if (CantAccessDatabase())
133 return;
134
135 sql::Statement url_statement(DB()->GetUniqueStatement(
136 base::StringPrintf("SELECT count(*) FROM %s",
137 kResourcePredictorUrlTableName).c_str()));
138 if (url_statement.Step())
139 UMA_HISTOGRAM_COUNTS("ResourcePrefetchPredictor.UrlTableRowCount",
140 url_statement.ColumnInt(0));
141 }
142
143 void ResourcePrefetchPredictorTables::GetAllRows(
144 std::vector<UrlTableRow>* url_row_buffer) {
145 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
146 if (CantAccessDatabase())
147 return;
148
149 CHECK(url_row_buffer);
150 url_row_buffer->clear();
151 sql::Statement url_statement(DB()->GetCachedStatement(SQL_FROM_HERE,
152 base::StringPrintf("SELECT * FROM %s",
153 kResourcePredictorUrlTableName).c_str()));
154
155 UrlTableRow url_row;
156 while (StepAndInitializeUrlTableRow(&url_statement, &url_row)) {
157 url_row.UpdateScore();
dominich 2012/05/21 16:16:53 why don't you store the score?
Shishir 2012/05/23 01:46:46 Not storing it right now because we want to run ex
158 url_row_buffer->push_back(url_row);
159 }
160 }
161
162 void ResourcePrefetchPredictorTables::UpdateRowsForUrl(
163 const GURL& main_page_url,
164 const std::vector<UrlTableRow>& row_buffer) {
165 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
166 if (CantAccessDatabase())
167 return;
168
169 DB()->BeginTransaction();
170
171 sql::Statement delete_statement(DB()->GetUniqueStatement(
dominich 2012/05/21 16:16:53 would it be more optimal to SELECT and then UPDATE
Shishir 2012/05/23 01:46:46 May not be, since we will end up updating all the
172 base::StringPrintf("DELETE FROM %s WHERE main_page_url='%s'",
173 kResourcePredictorUrlTableName,
174 main_page_url.spec().c_str()).c_str()));
175 if (!delete_statement.Run()) {
176 DB()->RollbackTransaction();
177 return;
178 }
179
180 for (int i = 0; i < static_cast<int>(row_buffer.size()); ++i) {
181 const UrlTableRow& row = row_buffer.at(i);
182
183 sql::Statement add_statement(
184 DB()->GetCachedStatement(
185 SQL_FROM_HERE,
186 base::StringPrintf(
187 "INSERT INTO %s "
188 "(main_page_url, resource_url, resource_type, number_of_hits, "
189 "number_of_misses, consecutive_misses, average_position) "
190 "VALUES (?,?,?,?,?,?,?)",
191 kResourcePredictorUrlTableName).c_str()));
192 BindUrlTableRowToStatement(row, &add_statement);
193 if (!add_statement.Run()) {
194 DB()->RollbackTransaction();
195 return;
196 }
197 }
198
199 DB()->CommitTransaction();
200 }
201
202 void ResourcePrefetchPredictorTables::DeleteUrlRows(
203 const std::vector<GURL>& urls) {
204 CHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
205 if (CantAccessDatabase())
206 return;
207
208 // These do not need to be a transaction.
209 for (int i = 0; i < static_cast<int>(urls.size()); ++i) {
210 sql::Statement delete_statement(DB()->GetCachedStatement(
211 SQL_FROM_HERE,
212 base::StringPrintf("DELETE FROM %s WHERE main_page_url='%s'",
213 kResourcePredictorUrlTableName,
214 urls[i].spec().c_str()).c_str()));
215 }
216 }
217
218 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698