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

Side by Side Diff: components/precache/core/precache_database.cc

Issue 27047003: Precache tracking database (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@precache
Patch Set: Added field trials Created 7 years, 1 month 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 2013 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 "components/precache/core/precache_database.h"
6
7 #include "base/metrics/histogram.h"
8 #include "base/time/time.h"
9 #include "components/precache/core/precache_statistics_table.h"
10 #include "components/precache/core/precache_url_table.h"
11 #include "sql/connection.h"
12 #include "url/gurl.h"
13
14 namespace {
15
16 // The number of days old that an entry in the precache URL table can be before
17 // it is considered "old" and is removed from the table.
18 const int64 kPrecacheHistoryExpiryPeriodDays = 60;
19
20 void RecordSingleDayPrecacheUMA(
21 const precache::PrecacheStatisticsTable::PrecacheStatistics& stats) {
22 UMA_HISTOGRAM_COUNTS("Precache.DailyPrecachedKB",
23 stats.precached_bytes / 1024);
24 UMA_HISTOGRAM_COUNTS("Precache.DailyDownloadedKB",
25 stats.downloaded_bytes / 1024);
26 UMA_HISTOGRAM_COUNTS("Precache.DailyDownloadedKB.Cellular",
27 stats.downloaded_bytes_cellular / 1024);
28 UMA_HISTOGRAM_COUNTS("Precache.DailySavedKB", stats.saved_bytes / 1024);
29 UMA_HISTOGRAM_COUNTS("Precache.DailySavedKB.Cellular",
30 stats.saved_bytes_cellular / 1024);
31
32 if (stats.saved_bytes + stats.downloaded_bytes > 0) {
33 UMA_HISTOGRAM_PERCENTAGE("Precache.DailySavingsPercentage",
34 stats.saved_bytes * 100.0 /
35 (stats.saved_bytes + stats.downloaded_bytes));
36 }
37
38 if (stats.saved_bytes_cellular + stats.downloaded_bytes_cellular > 0) {
39 UMA_HISTOGRAM_PERCENTAGE(
40 "Precache.DailySavingsPercentage.Cellular",
41 stats.saved_bytes_cellular * 100.0 /
42 (stats.saved_bytes_cellular + stats.downloaded_bytes_cellular));
43 }
44 }
45
46 } // namespace
47
48 namespace precache {
49
50 PrecacheDatabase::PrecacheDatabase()
51 : precache_url_table_(new PrecacheURLTable()),
52 precache_statistics_table_(new PrecacheStatisticsTable()) {
53 // A PrecacheDatabase can be constructed on any thread.
54 DetachFromThread();
55 }
56
57 PrecacheDatabase::~PrecacheDatabase() {
58 // Since the PrecacheDatabase is refcounted, it will only be deleted if there
59 // are no references remaining to it, meaning that it is not in use. Thus, it
60 // is safe to delete it, regardless of what thread we are on.
61 DetachFromThread();
62 }
63
64 void PrecacheDatabase::Init(scoped_ptr<sql::Connection> db) {
65 DCHECK(CalledOnValidThread());
66 DCHECK(!db_); // Init must only be called once.
67 DCHECK(db); // |db| must not be NULL.
68
69 db_.reset(db.release());
70 if (!IsDatabaseAccessible()) {
71 // Don't initialize the URL table or statistics table if unable to access
72 // the database.
73 return;
74 }
75
76 precache_url_table_->Init(db_.get());
77 precache_statistics_table_->Init(db_.get());
78 }
79
80 void PrecacheDatabase::ReportAndDeleteOldStats(const base::Time& end_date) {
81 DCHECK(CalledOnValidThread());
82 DCHECK(db_);
83
84 if (!IsDatabaseAccessible()) {
85 // Do nothing if unable to access the database.
86 return;
87 }
88
89 // Delete old precache history that has expired.
90 precache_url_table_->DeleteAllPrecachedBetween(
91 base::Time(),
92 end_date - base::TimeDelta::FromDays(kPrecacheHistoryExpiryPeriodDays));
93
94 PrecacheStatisticsTable::PrecacheStatisticsMap stats_map;
95 precache_statistics_table_->GetAllStatsBetween(base::Time(), end_date,
96 &stats_map);
97
98 // Report UMA for every row of old statistics in the statistics table. There
99 // won't be any rows in the statistics table for days when nothing was fetched
100 // or precached.
101 for (PrecacheStatisticsTable::PrecacheStatisticsMap::const_iterator it =
102 stats_map.begin();
103 it != stats_map.end(); ++it) {
104 RecordSingleDayPrecacheUMA(it->second);
105 }
106
107 precache_statistics_table_->DeleteAllStatsBetween(base::Time(), end_date);
108 }
109
110 void PrecacheDatabase::RecordURLFetched(const GURL& url,
111 const base::Time& fetch_time,
112 int64 size, bool was_cached,
113 bool is_precache,
114 bool is_connection_cellular) {
115 DCHECK(CalledOnValidThread());
116 DCHECK(db_);
117
118 if (!IsDatabaseAccessible()) {
119 // Don't track anything if unable to access the database.
120 return;
121 }
122
123 if (is_precache) {
124 if (was_cached && !precache_url_table_->HasURL(url)) {
125 // Since the precache came from the cache, and there's no entry in the
126 // URL table for the URL, this means that the resource was already in the
127 // cache because of user browsing. Thus, this precache had no effect, so
128 // ignore it.
129 return;
130 }
131
132 if (!was_cached) {
133 // The precache only counts as overhead if it was downloaded over the
134 // network.
135 PrecacheStatisticsTable::PrecacheStatistics stats;
136 stats.precached_bytes = size;
137 precache_statistics_table_->IncreaseDailyStats(fetch_time, stats);
138 }
139
140 // Use the URL table to keep track of URLs that are in the cache thanks to
141 // precaching. If a row for the URL already exists, than update the
142 // timestamp to |fetch_time|.
143 precache_url_table_->AddURL(url, fetch_time);
144 return;
145 }
146
147 if (!was_cached) {
148 // The fetch was served over the network during user browsing, so count it
149 // as downloaded bytes.
150 PrecacheStatisticsTable::PrecacheStatistics stats;
151 stats.downloaded_bytes = size;
152 if (is_connection_cellular) {
153 stats.downloaded_bytes_cellular = size;
154 }
155 precache_statistics_table_->IncreaseDailyStats(fetch_time, stats);
156
157 // Since the fetch was over the network during user browsing, delete any
158 // record of it having been precached from the URL table. If it had been
159 // precached, the resource must have expired.
160 precache_url_table_->DeleteURL(url);
161 return;
162 }
163
164 if (was_cached && precache_url_table_->HasURL(url)) {
165 // The fetch was served from the cache, and since there's an entry for this
166 // URL in the URL table, this means that the resource was served from the
167 // cache only because precaching put it there. Thus, precaching was helpful,
168 // so count the fetch as saved bytes.
169 PrecacheStatisticsTable::PrecacheStatistics stats;
170 stats.saved_bytes = size;
171 if (is_connection_cellular) {
172 stats.saved_bytes_cellular = size;
173 }
174 precache_statistics_table_->IncreaseDailyStats(fetch_time, stats);
175
176 precache_url_table_->DeleteURL(url);
177 }
178 }
179
180 bool PrecacheDatabase::IsDatabaseAccessible() const {
181 DCHECK(CalledOnValidThread());
182 DCHECK(db_);
183
184 return db_->is_open();
185 }
186
187 } // namespace precache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698