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 15 matching lines...) Expand all Loading... | |
| 26 #include "storage/common/fileapi/file_system_util.h" | 26 #include "storage/common/fileapi/file_system_util.h" |
| 27 | 27 |
| 28 using storage::DatabaseUtil; | 28 using storage::DatabaseUtil; |
| 29 | 29 |
| 30 namespace content { | 30 namespace content { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 // Delay for a moment after a value is set in anticipation | 34 // Delay for a moment after a value is set in anticipation |
| 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 = 10; |
|
michaeln
2015/05/14 01:33:48
Please don't hastily remove the commit rate limite
| |
| 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 kMaxBytesPerMinute = kPerStorageAreaQuota; |
|
michaeln
2015/05/14 01:33:48
Adjusting the values is ok, but this adjustment go
| |
| 41 const int kMaxCommitsPerHour = 6; | |
| 42 | 41 |
| 43 } // namespace | 42 } // namespace |
| 44 | 43 |
| 45 bool DOMStorageArea::s_aggressive_flushing_enabled_ = false; | 44 bool DOMStorageArea::s_aggressive_flushing_enabled_ = false; |
| 46 | 45 |
| 47 DOMStorageArea::RateLimiter::RateLimiter(size_t desired_rate, | 46 DOMStorageArea::RateLimiter::RateLimiter(size_t desired_rate, |
| 48 base::TimeDelta time_quantum) | 47 base::TimeDelta time_quantum) |
| 49 : rate_(desired_rate), samples_(0), time_quantum_(time_quantum) { | 48 : rate_(desired_rate), samples_(0), time_quantum_(time_quantum) { |
| 50 DCHECK_GT(desired_rate, 0ul); | 49 DCHECK_GT(desired_rate, 0ul); |
| 51 } | 50 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 : namespace_id_(kLocalStorageNamespaceId), | 101 : namespace_id_(kLocalStorageNamespaceId), |
| 103 origin_(origin), | 102 origin_(origin), |
| 104 directory_(directory), | 103 directory_(directory), |
| 105 task_runner_(task_runner), | 104 task_runner_(task_runner), |
| 106 map_(new DOMStorageMap(kPerStorageAreaQuota + | 105 map_(new DOMStorageMap(kPerStorageAreaQuota + |
| 107 kPerStorageAreaOverQuotaAllowance)), | 106 kPerStorageAreaOverQuotaAllowance)), |
| 108 is_initial_import_done_(true), | 107 is_initial_import_done_(true), |
| 109 is_shutdown_(false), | 108 is_shutdown_(false), |
| 110 commit_batches_in_flight_(0), | 109 commit_batches_in_flight_(0), |
| 111 start_time_(base::TimeTicks::Now()), | 110 start_time_(base::TimeTicks::Now()), |
| 112 data_rate_limiter_(kMaxBytesPerDay, base::TimeDelta::FromHours(24)), | 111 data_rate_limiter_(kMaxBytesPerMinute, base::TimeDelta::FromMinutes(1)) { |
| 113 commit_rate_limiter_(kMaxCommitsPerHour, base::TimeDelta::FromHours(1)) { | |
| 114 if (!directory.empty()) { | 112 if (!directory.empty()) { |
| 115 base::FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_)); | 113 base::FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_)); |
| 116 backing_.reset(new LocalStorageDatabaseAdapter(path)); | 114 backing_.reset(new LocalStorageDatabaseAdapter(path)); |
| 117 is_initial_import_done_ = false; | 115 is_initial_import_done_ = false; |
| 118 } | 116 } |
| 119 } | 117 } |
| 120 | 118 |
| 121 DOMStorageArea::DOMStorageArea(int64 namespace_id, | 119 DOMStorageArea::DOMStorageArea(int64 namespace_id, |
| 122 const std::string& persistent_namespace_id, | 120 const std::string& persistent_namespace_id, |
| 123 const GURL& origin, | 121 const GURL& origin, |
| 124 SessionStorageDatabase* session_storage_backing, | 122 SessionStorageDatabase* session_storage_backing, |
| 125 DOMStorageTaskRunner* task_runner) | 123 DOMStorageTaskRunner* task_runner) |
| 126 : namespace_id_(namespace_id), | 124 : namespace_id_(namespace_id), |
| 127 persistent_namespace_id_(persistent_namespace_id), | 125 persistent_namespace_id_(persistent_namespace_id), |
| 128 origin_(origin), | 126 origin_(origin), |
| 129 task_runner_(task_runner), | 127 task_runner_(task_runner), |
| 130 map_(new DOMStorageMap(kPerStorageAreaQuota + | 128 map_(new DOMStorageMap(kPerStorageAreaQuota + |
| 131 kPerStorageAreaOverQuotaAllowance)), | 129 kPerStorageAreaOverQuotaAllowance)), |
| 132 session_storage_backing_(session_storage_backing), | 130 session_storage_backing_(session_storage_backing), |
| 133 is_initial_import_done_(true), | 131 is_initial_import_done_(true), |
| 134 is_shutdown_(false), | 132 is_shutdown_(false), |
| 135 commit_batches_in_flight_(0), | 133 commit_batches_in_flight_(0), |
| 136 start_time_(base::TimeTicks::Now()), | 134 start_time_(base::TimeTicks::Now()), |
| 137 data_rate_limiter_(kMaxBytesPerDay, base::TimeDelta::FromHours(24)), | 135 data_rate_limiter_(kMaxBytesPerMinute, base::TimeDelta::FromMinutes(1)) { |
| 138 commit_rate_limiter_(kMaxCommitsPerHour, base::TimeDelta::FromHours(1)) { | |
| 139 DCHECK(namespace_id != kLocalStorageNamespaceId); | 136 DCHECK(namespace_id != kLocalStorageNamespaceId); |
| 140 if (session_storage_backing) { | 137 if (session_storage_backing) { |
| 141 backing_.reset(new SessionStorageDatabaseAdapter( | 138 backing_.reset(new SessionStorageDatabaseAdapter( |
| 142 session_storage_backing, persistent_namespace_id, origin)); | 139 session_storage_backing, persistent_namespace_id, origin)); |
| 143 is_initial_import_done_ = false; | 140 is_initial_import_done_ = false; |
| 144 } | 141 } |
| 145 } | 142 } |
| 146 | 143 |
| 147 DOMStorageArea::~DOMStorageArea() { | 144 DOMStorageArea::~DOMStorageArea() { |
| 148 } | 145 } |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 ComputeCommitDelay()); | 390 ComputeCommitDelay()); |
| 394 } | 391 } |
| 395 | 392 |
| 396 base::TimeDelta DOMStorageArea::ComputeCommitDelay() const { | 393 base::TimeDelta DOMStorageArea::ComputeCommitDelay() const { |
| 397 if (s_aggressive_flushing_enabled_) | 394 if (s_aggressive_flushing_enabled_) |
| 398 return base::TimeDelta::FromSeconds(1); | 395 return base::TimeDelta::FromSeconds(1); |
| 399 | 396 |
| 400 base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_; | 397 base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_; |
| 401 base::TimeDelta delay = std::max( | 398 base::TimeDelta delay = std::max( |
| 402 base::TimeDelta::FromSeconds(kCommitDefaultDelaySecs), | 399 base::TimeDelta::FromSeconds(kCommitDefaultDelaySecs), |
| 403 std::max(commit_rate_limiter_.ComputeDelayNeeded(elapsed_time), | 400 data_rate_limiter_.ComputeDelayNeeded(elapsed_time)); |
| 404 data_rate_limiter_.ComputeDelayNeeded(elapsed_time))); | |
| 405 UMA_HISTOGRAM_LONG_TIMES("LocalStorage.CommitDelay", delay); | 401 UMA_HISTOGRAM_LONG_TIMES("LocalStorage.CommitDelay", delay); |
| 406 return delay; | 402 return delay; |
| 407 } | 403 } |
| 408 | 404 |
| 409 void DOMStorageArea::OnCommitTimer() { | 405 void DOMStorageArea::OnCommitTimer() { |
| 410 if (is_shutdown_) | 406 if (is_shutdown_) |
| 411 return; | 407 return; |
| 412 | 408 |
| 413 // It's possible that there is nothing to commit if an immediate | 409 // It's possible that there is nothing to commit if an immediate |
| 414 // commit occured after the timer was scheduled but before it fired. | 410 // commit occured after the timer was scheduled but before it fired. |
| 415 if (!commit_batch_) | 411 if (!commit_batch_) |
| 416 return; | 412 return; |
| 417 | 413 |
| 418 PostCommitTask(); | 414 PostCommitTask(); |
| 419 } | 415 } |
| 420 | 416 |
| 421 void DOMStorageArea::PostCommitTask() { | 417 void DOMStorageArea::PostCommitTask() { |
| 422 if (is_shutdown_ || !commit_batch_) | 418 if (is_shutdown_ || !commit_batch_) |
| 423 return; | 419 return; |
| 424 | 420 |
| 425 DCHECK(backing_.get()); | 421 DCHECK(backing_.get()); |
| 426 | 422 |
| 427 commit_rate_limiter_.add_samples(1); | |
| 428 data_rate_limiter_.add_samples(commit_batch_->GetDataSize()); | 423 data_rate_limiter_.add_samples(commit_batch_->GetDataSize()); |
| 429 | 424 |
| 430 // This method executes on the primary sequence, we schedule | 425 // This method executes on the primary sequence, we schedule |
| 431 // a task for immediate execution on the commit sequence. | 426 // a task for immediate execution on the commit sequence. |
| 432 DCHECK(task_runner_->IsRunningOnPrimarySequence()); | 427 DCHECK(task_runner_->IsRunningOnPrimarySequence()); |
| 433 bool success = task_runner_->PostShutdownBlockingTask( | 428 bool success = task_runner_->PostShutdownBlockingTask( |
| 434 FROM_HERE, | 429 FROM_HERE, |
| 435 DOMStorageTaskRunner::COMMIT_SEQUENCE, | 430 DOMStorageTaskRunner::COMMIT_SEQUENCE, |
| 436 base::Bind(&DOMStorageArea::CommitChanges, this, | 431 base::Bind(&DOMStorageArea::CommitChanges, this, |
| 437 base::Owned(commit_batch_.release()))); | 432 base::Owned(commit_batch_.release()))); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 commit_batch_->clear_all_first, | 470 commit_batch_->clear_all_first, |
| 476 commit_batch_->changed_values); | 471 commit_batch_->changed_values); |
| 477 DCHECK(success); | 472 DCHECK(success); |
| 478 } | 473 } |
| 479 commit_batch_.reset(); | 474 commit_batch_.reset(); |
| 480 backing_.reset(); | 475 backing_.reset(); |
| 481 session_storage_backing_ = NULL; | 476 session_storage_backing_ = NULL; |
| 482 } | 477 } |
| 483 | 478 |
| 484 } // namespace content | 479 } // namespace content |
| OLD | NEW |