Chromium Code Reviews| Index: chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc |
| diff --git a/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc b/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc |
| index 25162d53964d0fa4bc42e665d684ac371734e2a1..c4daea6ecffb3a9aedd76e10865e29ee78d8b113 100644 |
| --- a/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc |
| +++ b/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc |
| @@ -9,6 +9,7 @@ |
| #include "base/memory/scoped_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/metrics/histogram.h" |
| +#include "base/stl_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "chrome/browser/value_store/value_store_util.h" |
| #include "extensions/common/extension_api.h" |
| @@ -87,17 +88,7 @@ scoped_ptr<ValueStore::Error> QuotaExceededError(Resource resource, |
| SettingsStorageQuotaEnforcer::SettingsStorageQuotaEnforcer( |
| const Limits& limits, ValueStore* delegate) |
| : limits_(limits), delegate_(delegate), used_total_(0) { |
| - ReadResult maybe_settings = delegate_->Get(); |
| - if (maybe_settings->HasError()) { |
| - LOG(WARNING) << "Failed to get initial settings for quota: " << |
| - maybe_settings->error().message; |
| - return; |
| - } |
| - |
| - for (base::DictionaryValue::Iterator it(maybe_settings->settings()); |
| - !it.IsAtEnd(); it.Advance()) { |
| - Allocate(it.key(), it.value(), &used_total_, &used_per_setting_); |
| - } |
| + CalculateUsage(); |
| } |
| SettingsStorageQuotaEnforcer::~SettingsStorageQuotaEnforcer() {} |
| @@ -229,10 +220,54 @@ ValueStore::WriteResult SettingsStorageQuotaEnforcer::Clear() { |
| return result.Pass(); |
| } |
| - while (!used_per_setting_.empty()) { |
| - Free(&used_total_, &used_per_setting_, used_per_setting_.begin()->first); |
| - } |
| + used_per_setting_.clear(); |
| + used_total_ = 0; |
| return result.Pass(); |
| } |
| +bool SettingsStorageQuotaEnforcer::Restore() { |
| + if (!delegate_->Restore()) { |
| + // If we failed, we can't calculate the usage - that's okay, though, because |
| + // next time we Restore() (if it succeeds) we will recalculate usage anyway. |
| + // So reset storage counters now to free up resources. |
| + used_per_setting_.clear(); |
| + used_total_ = 0u; |
| + return false; |
| + } |
| + CalculateUsage(); |
| + return true; |
| +} |
| + |
| +bool SettingsStorageQuotaEnforcer::RestoreKey(const std::string& key) { |
| + if (!delegate_->RestoreKey(key)) |
| + return false; |
| + |
| + ReadResult result = Get(key); |
| + // If the key was deleted as a result of the Restore() call, free it. |
| + if (!result->settings().HasKey(key) && ContainsKey(used_per_setting_, key)) |
| + Free(&used_total_, &used_per_setting_, key); |
| + return true; |
| +} |
| + |
| +void SettingsStorageQuotaEnforcer::CalculateUsage() { |
|
not at google - send to devlin
2014/02/19 21:25:29
yeah, this is all complex enough to warrant testin
Devlin
2014/02/19 23:12:28
Will do in follow-up, if that's okay.
|
| + ReadResult maybe_settings = delegate_->Get(); |
| + if (maybe_settings->HasError()) { |
| + // Try to restore the database if it's corrupt. |
| + if (maybe_settings->error().code == ValueStore::CORRUPTION && |
| + delegate_->Restore()) { |
| + maybe_settings = delegate_->Get(); |
| + } else { |
| + LOG(WARNING) << "Failed to get settings for quota:" |
| + << maybe_settings->error().message; |
| + return; |
| + } |
| + } |
| + |
| + for (base::DictionaryValue::Iterator it(maybe_settings->settings()); |
| + !it.IsAtEnd(); |
| + it.Advance()) { |
| + Allocate(it.key(), it.value(), &used_total_, &used_per_setting_); |
| + } |
| +} |
| + |
| } // namespace extensions |