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() { |
+ 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 |