OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "webkit/browser/quota/quota_temporary_storage_evictor.h" | 5 #include "storage/browser/quota/quota_temporary_storage_evictor.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "url/gurl.h" | 11 #include "url/gurl.h" |
12 #include "webkit/browser/quota/quota_manager.h" | 12 #include "storage/browser/quota/quota_manager.h" |
13 | 13 |
14 #define UMA_HISTOGRAM_MBYTES(name, sample) \ | 14 #define UMA_HISTOGRAM_MBYTES(name, sample) \ |
15 UMA_HISTOGRAM_CUSTOM_COUNTS( \ | 15 UMA_HISTOGRAM_CUSTOM_COUNTS((name), \ |
16 (name), static_cast<int>((sample) / kMBytes), \ | 16 static_cast<int>((sample) / kMBytes), \ |
17 1, 10 * 1024 * 1024 /* 10TB */, 100) | 17 1, \ |
| 18 10 * 1024 * 1024 /* 10TB */, \ |
| 19 100) |
18 | 20 |
19 #define UMA_HISTOGRAM_MINUTES(name, sample) \ | 21 #define UMA_HISTOGRAM_MINUTES(name, sample) \ |
20 UMA_HISTOGRAM_CUSTOM_TIMES( \ | 22 UMA_HISTOGRAM_CUSTOM_TIMES((name), \ |
21 (name), (sample), \ | 23 (sample), \ |
22 base::TimeDelta::FromMinutes(1), \ | 24 base::TimeDelta::FromMinutes(1), \ |
23 base::TimeDelta::FromDays(1), 50) | 25 base::TimeDelta::FromDays(1), \ |
| 26 50) |
24 | 27 |
25 namespace { | 28 namespace { |
26 const int64 kMBytes = 1024 * 1024; | 29 const int64 kMBytes = 1024 * 1024; |
27 const double kUsageRatioToStartEviction = 0.7; | 30 const double kUsageRatioToStartEviction = 0.7; |
28 const int kThresholdOfErrorsToStopEviction = 5; | 31 const int kThresholdOfErrorsToStopEviction = 5; |
29 const int kHistogramReportIntervalMinutes = 60; | 32 const int kHistogramReportIntervalMinutes = 60; |
30 } | 33 } |
31 | 34 |
32 namespace quota { | 35 namespace quota { |
33 | 36 |
(...skipping 26 matching lines...) Expand all Loading... |
60 } | 63 } |
61 | 64 |
62 void QuotaTemporaryStorageEvictor::GetStatistics( | 65 void QuotaTemporaryStorageEvictor::GetStatistics( |
63 std::map<std::string, int64>* statistics) { | 66 std::map<std::string, int64>* statistics) { |
64 DCHECK(statistics); | 67 DCHECK(statistics); |
65 | 68 |
66 (*statistics)["errors-on-evicting-origin"] = | 69 (*statistics)["errors-on-evicting-origin"] = |
67 statistics_.num_errors_on_evicting_origin; | 70 statistics_.num_errors_on_evicting_origin; |
68 (*statistics)["errors-on-getting-usage-and-quota"] = | 71 (*statistics)["errors-on-getting-usage-and-quota"] = |
69 statistics_.num_errors_on_getting_usage_and_quota; | 72 statistics_.num_errors_on_getting_usage_and_quota; |
70 (*statistics)["evicted-origins"] = | 73 (*statistics)["evicted-origins"] = statistics_.num_evicted_origins; |
71 statistics_.num_evicted_origins; | 74 (*statistics)["eviction-rounds"] = statistics_.num_eviction_rounds; |
72 (*statistics)["eviction-rounds"] = | |
73 statistics_.num_eviction_rounds; | |
74 (*statistics)["skipped-eviction-rounds"] = | 75 (*statistics)["skipped-eviction-rounds"] = |
75 statistics_.num_skipped_eviction_rounds; | 76 statistics_.num_skipped_eviction_rounds; |
76 } | 77 } |
77 | 78 |
78 void QuotaTemporaryStorageEvictor::ReportPerRoundHistogram() { | 79 void QuotaTemporaryStorageEvictor::ReportPerRoundHistogram() { |
79 DCHECK(round_statistics_.in_round); | 80 DCHECK(round_statistics_.in_round); |
80 DCHECK(round_statistics_.is_initialized); | 81 DCHECK(round_statistics_.is_initialized); |
81 | 82 |
82 base::Time now = base::Time::Now(); | 83 base::Time now = base::Time::Now(); |
83 UMA_HISTOGRAM_TIMES("Quota.TimeSpentToAEvictionRound", | 84 UMA_HISTOGRAM_TIMES("Quota.TimeSpentToAEvictionRound", |
84 now - round_statistics_.start_time); | 85 now - round_statistics_.start_time); |
85 if (!time_of_end_of_last_round_.is_null()) | 86 if (!time_of_end_of_last_round_.is_null()) |
86 UMA_HISTOGRAM_MINUTES("Quota.TimeDeltaOfEvictionRounds", | 87 UMA_HISTOGRAM_MINUTES("Quota.TimeDeltaOfEvictionRounds", |
87 now - time_of_end_of_last_round_); | 88 now - time_of_end_of_last_round_); |
88 UMA_HISTOGRAM_MBYTES("Quota.UsageOverageOfTemporaryGlobalStorage", | 89 UMA_HISTOGRAM_MBYTES("Quota.UsageOverageOfTemporaryGlobalStorage", |
89 round_statistics_.usage_overage_at_round); | 90 round_statistics_.usage_overage_at_round); |
90 UMA_HISTOGRAM_MBYTES("Quota.DiskspaceShortage", | 91 UMA_HISTOGRAM_MBYTES("Quota.DiskspaceShortage", |
91 round_statistics_.diskspace_shortage_at_round); | 92 round_statistics_.diskspace_shortage_at_round); |
92 UMA_HISTOGRAM_MBYTES("Quota.EvictedBytesPerRound", | 93 UMA_HISTOGRAM_MBYTES("Quota.EvictedBytesPerRound", |
93 round_statistics_.usage_on_beginning_of_round - | 94 round_statistics_.usage_on_beginning_of_round - |
94 round_statistics_.usage_on_end_of_round); | 95 round_statistics_.usage_on_end_of_round); |
95 UMA_HISTOGRAM_COUNTS("Quota.NumberOfEvictedOriginsPerRound", | 96 UMA_HISTOGRAM_COUNTS("Quota.NumberOfEvictedOriginsPerRound", |
96 round_statistics_.num_evicted_origins_in_round); | 97 round_statistics_.num_evicted_origins_in_round); |
97 } | 98 } |
98 | 99 |
99 void QuotaTemporaryStorageEvictor::ReportPerHourHistogram() { | 100 void QuotaTemporaryStorageEvictor::ReportPerHourHistogram() { |
100 Statistics stats_in_hour(statistics_); | 101 Statistics stats_in_hour(statistics_); |
101 stats_in_hour.subtract_assign(previous_statistics_); | 102 stats_in_hour.subtract_assign(previous_statistics_); |
102 previous_statistics_ = statistics_; | 103 previous_statistics_ = statistics_; |
103 | 104 |
104 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnEvictingOriginPerHour", | 105 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnEvictingOriginPerHour", |
(...skipping 29 matching lines...) Expand all Loading... |
134 } | 135 } |
135 | 136 |
136 void QuotaTemporaryStorageEvictor::Start() { | 137 void QuotaTemporaryStorageEvictor::Start() { |
137 DCHECK(CalledOnValidThread()); | 138 DCHECK(CalledOnValidThread()); |
138 StartEvictionTimerWithDelay(0); | 139 StartEvictionTimerWithDelay(0); |
139 | 140 |
140 if (histogram_timer_.IsRunning()) | 141 if (histogram_timer_.IsRunning()) |
141 return; | 142 return; |
142 | 143 |
143 histogram_timer_.Start( | 144 histogram_timer_.Start( |
144 FROM_HERE, base::TimeDelta::FromMinutes(kHistogramReportIntervalMinutes), | 145 FROM_HERE, |
145 this, &QuotaTemporaryStorageEvictor::ReportPerHourHistogram); | 146 base::TimeDelta::FromMinutes(kHistogramReportIntervalMinutes), |
| 147 this, |
| 148 &QuotaTemporaryStorageEvictor::ReportPerHourHistogram); |
146 } | 149 } |
147 | 150 |
148 void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) { | 151 void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) { |
149 if (eviction_timer_.IsRunning()) | 152 if (eviction_timer_.IsRunning()) |
150 return; | 153 return; |
151 eviction_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms), | 154 eviction_timer_.Start(FROM_HERE, |
152 this, &QuotaTemporaryStorageEvictor::ConsiderEviction); | 155 base::TimeDelta::FromMilliseconds(delay_ms), |
| 156 this, |
| 157 &QuotaTemporaryStorageEvictor::ConsiderEviction); |
153 } | 158 } |
154 | 159 |
155 void QuotaTemporaryStorageEvictor::ConsiderEviction() { | 160 void QuotaTemporaryStorageEvictor::ConsiderEviction() { |
156 OnEvictionRoundStarted(); | 161 OnEvictionRoundStarted(); |
157 | 162 |
158 // Get usage and disk space, then continue. | 163 // Get usage and disk space, then continue. |
159 quota_eviction_handler_->GetUsageAndQuotaForEviction( | 164 quota_eviction_handler_->GetUsageAndQuotaForEviction( |
160 base::Bind(&QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction, | 165 base::Bind(&QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction, |
161 weak_factory_.GetWeakPtr())); | 166 weak_factory_.GetWeakPtr())); |
162 } | 167 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 void QuotaTemporaryStorageEvictor::OnGotLRUOrigin(const GURL& origin) { | 225 void QuotaTemporaryStorageEvictor::OnGotLRUOrigin(const GURL& origin) { |
221 DCHECK(CalledOnValidThread()); | 226 DCHECK(CalledOnValidThread()); |
222 | 227 |
223 if (origin.is_empty()) { | 228 if (origin.is_empty()) { |
224 if (repeated_eviction_) | 229 if (repeated_eviction_) |
225 StartEvictionTimerWithDelay(interval_ms_); | 230 StartEvictionTimerWithDelay(interval_ms_); |
226 OnEvictionRoundFinished(); | 231 OnEvictionRoundFinished(); |
227 return; | 232 return; |
228 } | 233 } |
229 | 234 |
230 quota_eviction_handler_->EvictOriginData(origin, kStorageTypeTemporary, | 235 quota_eviction_handler_->EvictOriginData( |
231 base::Bind( | 236 origin, |
232 &QuotaTemporaryStorageEvictor::OnEvictionComplete, | 237 kStorageTypeTemporary, |
233 weak_factory_.GetWeakPtr())); | 238 base::Bind(&QuotaTemporaryStorageEvictor::OnEvictionComplete, |
| 239 weak_factory_.GetWeakPtr())); |
234 } | 240 } |
235 | 241 |
236 void QuotaTemporaryStorageEvictor::OnEvictionComplete( | 242 void QuotaTemporaryStorageEvictor::OnEvictionComplete(QuotaStatusCode status) { |
237 QuotaStatusCode status) { | |
238 DCHECK(CalledOnValidThread()); | 243 DCHECK(CalledOnValidThread()); |
239 | 244 |
240 // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is | 245 // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is |
241 // ok. No need to deal with the case that all of the Delete operations fail | 246 // ok. No need to deal with the case that all of the Delete operations fail |
242 // for a certain origin. It doesn't result in trying to evict the same | 247 // for a certain origin. It doesn't result in trying to evict the same |
243 // origin permanently. The evictor skips origins which had deletion errors | 248 // origin permanently. The evictor skips origins which had deletion errors |
244 // a few times. | 249 // a few times. |
245 | 250 |
246 if (status == kQuotaStatusOk) { | 251 if (status == kQuotaStatusOk) { |
247 ++statistics_.num_evicted_origins; | 252 ++statistics_.num_evicted_origins; |
248 ++round_statistics_.num_evicted_origins_in_round; | 253 ++round_statistics_.num_evicted_origins_in_round; |
249 // We many need to get rid of more space so reconsider immediately. | 254 // We many need to get rid of more space so reconsider immediately. |
250 ConsiderEviction(); | 255 ConsiderEviction(); |
251 } else { | 256 } else { |
252 ++statistics_.num_errors_on_evicting_origin; | 257 ++statistics_.num_errors_on_evicting_origin; |
253 if (repeated_eviction_) { | 258 if (repeated_eviction_) { |
254 // Sleep for a while and retry again until we see too many errors. | 259 // Sleep for a while and retry again until we see too many errors. |
255 StartEvictionTimerWithDelay(interval_ms_); | 260 StartEvictionTimerWithDelay(interval_ms_); |
256 } | 261 } |
257 OnEvictionRoundFinished(); | 262 OnEvictionRoundFinished(); |
258 } | 263 } |
259 } | 264 } |
260 | 265 |
261 } // namespace quota | 266 } // namespace quota |
OLD | NEW |