Chromium Code Reviews| 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 |