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 "content/browser/dom_storage/dom_storage_area.h" | 5 #include "content/browser/dom_storage/dom_storage_area.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 24 matching lines...) Expand all Loading... | |
35 // of other values being set, so changes are batched. | 35 // of other values being set, so changes are batched. |
36 const int kCommitDefaultDelaySecs = 5; | 36 const int kCommitDefaultDelaySecs = 5; |
37 | 37 |
38 // To avoid excessive IO we apply limits to the amount of data being written | 38 // To avoid excessive IO we apply limits to the amount of data being written |
39 // and the frequency of writes. The specific values used are somewhat arbitrary. | 39 // and the frequency of writes. The specific values used are somewhat arbitrary. |
40 const int kMaxBytesPerDay = kPerStorageAreaQuota * 2; | 40 const int kMaxBytesPerDay = kPerStorageAreaQuota * 2; |
41 const int kMaxCommitsPerHour = 6; | 41 const int kMaxCommitsPerHour = 6; |
42 | 42 |
43 } // namespace | 43 } // namespace |
44 | 44 |
45 bool DOMStorageArea::s_aggressive_flushing_enabled_ = false; | |
46 | |
45 DOMStorageArea::RateLimiter::RateLimiter(size_t desired_rate, | 47 DOMStorageArea::RateLimiter::RateLimiter(size_t desired_rate, |
46 base::TimeDelta time_quantum) | 48 base::TimeDelta time_quantum) |
47 : rate_(desired_rate), samples_(0), time_quantum_(time_quantum) { | 49 : rate_(desired_rate), samples_(0), time_quantum_(time_quantum) { |
48 DCHECK_GT(desired_rate, 0ul); | 50 DCHECK_GT(desired_rate, 0ul); |
49 } | 51 } |
50 | 52 |
51 base::TimeDelta DOMStorageArea::RateLimiter::ComputeTimeNeeded() const { | 53 base::TimeDelta DOMStorageArea::RateLimiter::ComputeTimeNeeded() const { |
52 return time_quantum_ * (samples_ / rate_); | 54 return time_quantum_ * (samples_ / rate_); |
53 } | 55 } |
54 | 56 |
(...skipping 28 matching lines...) Expand all Loading... | |
83 } | 85 } |
84 | 86 |
85 // static | 87 // static |
86 GURL DOMStorageArea::OriginFromDatabaseFileName(const base::FilePath& name) { | 88 GURL DOMStorageArea::OriginFromDatabaseFileName(const base::FilePath& name) { |
87 DCHECK(name.MatchesExtension(kDatabaseFileExtension)); | 89 DCHECK(name.MatchesExtension(kDatabaseFileExtension)); |
88 std::string origin_id = | 90 std::string origin_id = |
89 name.BaseName().RemoveExtension().MaybeAsASCII(); | 91 name.BaseName().RemoveExtension().MaybeAsASCII(); |
90 return storage::GetOriginFromIdentifier(origin_id); | 92 return storage::GetOriginFromIdentifier(origin_id); |
91 } | 93 } |
92 | 94 |
95 // Commence aggressive flushing. This should be called early in the startup - | |
96 // before any localStorage writing. Currently scheduled writes will not be | |
97 // rescheduled and will be flushed at the scheduled time after which aggressive | |
98 // flushing will commence. | |
michaeln
2015/05/07 23:19:03
maybe put the comment in the .h file
cmumford
2015/05/08 16:02:48
Done.
| |
99 void DOMStorageArea::EnableAggressiveCommitDelay() { | |
100 s_aggressive_flushing_enabled_ = true; | |
101 } | |
102 | |
93 DOMStorageArea::DOMStorageArea(const GURL& origin, | 103 DOMStorageArea::DOMStorageArea(const GURL& origin, |
94 const base::FilePath& directory, | 104 const base::FilePath& directory, |
95 DOMStorageTaskRunner* task_runner) | 105 DOMStorageTaskRunner* task_runner) |
96 : namespace_id_(kLocalStorageNamespaceId), | 106 : namespace_id_(kLocalStorageNamespaceId), |
97 origin_(origin), | 107 origin_(origin), |
98 directory_(directory), | 108 directory_(directory), |
99 task_runner_(task_runner), | 109 task_runner_(task_runner), |
100 map_(new DOMStorageMap(kPerStorageAreaQuota + | 110 map_(new DOMStorageMap(kPerStorageAreaQuota + |
101 kPerStorageAreaOverQuotaAllowance)), | 111 kPerStorageAreaOverQuotaAllowance)), |
102 is_initial_import_done_(true), | 112 is_initial_import_done_(true), |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 // started after the commits have happened. | 391 // started after the commits have happened. |
382 if (commit_batches_in_flight_) | 392 if (commit_batches_in_flight_) |
383 return; | 393 return; |
384 | 394 |
385 task_runner_->PostDelayedTask( | 395 task_runner_->PostDelayedTask( |
386 FROM_HERE, base::Bind(&DOMStorageArea::OnCommitTimer, this), | 396 FROM_HERE, base::Bind(&DOMStorageArea::OnCommitTimer, this), |
387 ComputeCommitDelay()); | 397 ComputeCommitDelay()); |
388 } | 398 } |
389 | 399 |
390 base::TimeDelta DOMStorageArea::ComputeCommitDelay() const { | 400 base::TimeDelta DOMStorageArea::ComputeCommitDelay() const { |
391 base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_; | 401 base::TimeDelta delay; |
392 base::TimeDelta delay = std::max( | 402 if (s_aggressive_flushing_enabled_) { |
393 base::TimeDelta::FromSeconds(kCommitDefaultDelaySecs), | 403 // Calculate very short delay to flush unwritten data soon. Used for |
394 std::max(commit_rate_limiter_.ComputeDelayNeeded(elapsed_time), | 404 // Chromium hosts that do not write data during shutdown (Android WebView). |
395 data_rate_limiter_.ComputeDelayNeeded(elapsed_time))); | 405 // More info at http://crbug.com/479767 |
michaeln
2015/05/07 23:19:03
nit: Given the nicely named methods and members, m
cmumford
2015/05/08 16:02:48
Done.
| |
396 UMA_HISTOGRAM_LONG_TIMES("LocalStorage.CommitDelay", delay); | 406 delay = base::TimeDelta::FromSeconds(1); |
407 } else { | |
408 base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_; | |
409 delay = | |
410 std::max(base::TimeDelta::FromSeconds(kCommitDefaultDelaySecs), | |
411 std::max(commit_rate_limiter_.ComputeDelayNeeded(elapsed_time), | |
412 data_rate_limiter_.ComputeDelayNeeded(elapsed_time))); | |
413 UMA_HISTOGRAM_LONG_TIMES("LocalStorage.CommitDelay", delay); | |
414 } | |
397 return delay; | 415 return delay; |
398 } | 416 } |
399 | 417 |
400 void DOMStorageArea::OnCommitTimer() { | 418 void DOMStorageArea::OnCommitTimer() { |
401 if (is_shutdown_) | 419 if (is_shutdown_) |
402 return; | 420 return; |
403 | 421 |
404 // It's possible that there is nothing to commit if an immediate | 422 // It's possible that there is nothing to commit if an immediate |
405 // commit occured after the timer was scheduled but before it fired. | 423 // commit occured after the timer was scheduled but before it fired. |
406 if (!commit_batch_) | 424 if (!commit_batch_) |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
466 commit_batch_->clear_all_first, | 484 commit_batch_->clear_all_first, |
467 commit_batch_->changed_values); | 485 commit_batch_->changed_values); |
468 DCHECK(success); | 486 DCHECK(success); |
469 } | 487 } |
470 commit_batch_.reset(); | 488 commit_batch_.reset(); |
471 backing_.reset(); | 489 backing_.reset(); |
472 session_storage_backing_ = NULL; | 490 session_storage_backing_ = NULL; |
473 } | 491 } |
474 | 492 |
475 } // namespace content | 493 } // namespace content |
OLD | NEW |