Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1707)

Unified Diff: chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc

Issue 189263013: Move extensions storage API implementation to src/extensions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase (move_storage) Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
deleted file mode 100644
index 30e976a259159b9dc0d56772648cdf8d0d5f8ec8..0000000000000000000000000000000000000000
--- a/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.h"
-
-#include "base/bind.h"
-#include "base/json/json_writer.h"
-#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 "extensions/browser/value_store/value_store_util.h"
-#include "extensions/common/extension_api.h"
-
-namespace util = value_store_util;
-
-namespace extensions {
-
-namespace {
-
-// Resources there are a quota for.
-enum Resource {
- QUOTA_BYTES,
- QUOTA_BYTES_PER_ITEM,
- MAX_ITEMS
-};
-
-// Allocates a setting in a record of total and per-setting usage.
-void Allocate(
- const std::string& key,
- const base::Value& value,
- size_t* used_total,
- std::map<std::string, size_t>* used_per_setting) {
- // Calculate the setting size based on its JSON serialization size.
- // TODO(kalman): Does this work with different encodings?
- // TODO(kalman): This is duplicating work that the leveldb delegate
- // implementation is about to do, and it would be nice to avoid this.
- std::string value_as_json;
- base::JSONWriter::Write(&value, &value_as_json);
- size_t new_size = key.size() + value_as_json.size();
- size_t existing_size = (*used_per_setting)[key];
-
- *used_total += (new_size - existing_size);
- (*used_per_setting)[key] = new_size;
-}
-
-// Frees the allocation of a setting in a record of total and per-setting usage.
-void Free(
- size_t* used_total,
- std::map<std::string, size_t>* used_per_setting,
- const std::string& key) {
- *used_total -= (*used_per_setting)[key];
- used_per_setting->erase(key);
-}
-
-scoped_ptr<ValueStore::Error> QuotaExceededError(Resource resource,
- scoped_ptr<std::string> key) {
- const char* name = NULL;
- // TODO(kalman): These hisograms are both silly and untracked. Fix.
- switch (resource) {
- case QUOTA_BYTES:
- name = "QUOTA_BYTES";
- UMA_HISTOGRAM_COUNTS_100(
- "Extensions.SettingsQuotaExceeded.TotalBytes", 1);
- break;
- case QUOTA_BYTES_PER_ITEM:
- name = "QUOTA_BYTES_PER_ITEM";
- UMA_HISTOGRAM_COUNTS_100(
- "Extensions.SettingsQuotaExceeded.BytesPerSetting", 1);
- break;
- case MAX_ITEMS:
- name = "MAX_ITEMS";
- UMA_HISTOGRAM_COUNTS_100(
- "Extensions.SettingsQuotaExceeded.KeyCount", 1);
- break;
- }
- CHECK(name);
- return make_scoped_ptr(new ValueStore::Error(
- ValueStore::QUOTA_EXCEEDED,
- base::StringPrintf("%s quota exceeded", name),
- key.Pass()));
-}
-
-} // namespace
-
-SettingsStorageQuotaEnforcer::SettingsStorageQuotaEnforcer(
- const Limits& limits, ValueStore* delegate)
- : limits_(limits), delegate_(delegate), used_total_(0) {
- CalculateUsage();
-}
-
-SettingsStorageQuotaEnforcer::~SettingsStorageQuotaEnforcer() {}
-
-size_t SettingsStorageQuotaEnforcer::GetBytesInUse(const std::string& key) {
- std::map<std::string, size_t>::iterator maybe_used =
- used_per_setting_.find(key);
- return maybe_used == used_per_setting_.end() ? 0u : maybe_used->second;
-}
-
-size_t SettingsStorageQuotaEnforcer::GetBytesInUse(
- const std::vector<std::string>& keys) {
- size_t used = 0;
- for (std::vector<std::string>::const_iterator it = keys.begin();
- it != keys.end(); ++it) {
- used += GetBytesInUse(*it);
- }
- return used;
-}
-
-size_t SettingsStorageQuotaEnforcer::GetBytesInUse() {
- // All ValueStore implementations rely on GetBytesInUse being
- // implemented here.
- return used_total_;
-}
-
-ValueStore::ReadResult SettingsStorageQuotaEnforcer::Get(
- const std::string& key) {
- return delegate_->Get(key);
-}
-
-ValueStore::ReadResult SettingsStorageQuotaEnforcer::Get(
- const std::vector<std::string>& keys) {
- return delegate_->Get(keys);
-}
-
-ValueStore::ReadResult SettingsStorageQuotaEnforcer::Get() {
- return delegate_->Get();
-}
-
-ValueStore::WriteResult SettingsStorageQuotaEnforcer::Set(
- WriteOptions options, const std::string& key, const base::Value& value) {
- size_t new_used_total = used_total_;
- std::map<std::string, size_t> new_used_per_setting = used_per_setting_;
- Allocate(key, value, &new_used_total, &new_used_per_setting);
-
- if (!(options & IGNORE_QUOTA)) {
- if (new_used_total > limits_.quota_bytes) {
- return MakeWriteResult(
- QuotaExceededError(QUOTA_BYTES, util::NewKey(key)));
- }
- if (new_used_per_setting[key] > limits_.quota_bytes_per_item) {
- return MakeWriteResult(
- QuotaExceededError(QUOTA_BYTES_PER_ITEM, util::NewKey(key)));
- }
- if (new_used_per_setting.size() > limits_.max_items)
- return MakeWriteResult(QuotaExceededError(MAX_ITEMS, util::NewKey(key)));
- }
-
- WriteResult result = delegate_->Set(options, key, value);
- if (result->HasError()) {
- return result.Pass();
- }
-
- used_total_ = new_used_total;
- used_per_setting_.swap(new_used_per_setting);
- return result.Pass();
-}
-
-ValueStore::WriteResult SettingsStorageQuotaEnforcer::Set(
- WriteOptions options, const base::DictionaryValue& values) {
- size_t new_used_total = used_total_;
- std::map<std::string, size_t> new_used_per_setting = used_per_setting_;
- for (base::DictionaryValue::Iterator it(values); !it.IsAtEnd();
- it.Advance()) {
- Allocate(it.key(), it.value(), &new_used_total, &new_used_per_setting);
-
- if (!(options & IGNORE_QUOTA) &&
- new_used_per_setting[it.key()] > limits_.quota_bytes_per_item) {
- return MakeWriteResult(
- QuotaExceededError(QUOTA_BYTES_PER_ITEM, util::NewKey(it.key())));
- }
- }
-
- if (!(options & IGNORE_QUOTA)) {
- if (new_used_total > limits_.quota_bytes)
- return MakeWriteResult(QuotaExceededError(QUOTA_BYTES, util::NoKey()));
- if (new_used_per_setting.size() > limits_.max_items)
- return MakeWriteResult(QuotaExceededError(MAX_ITEMS, util::NoKey()));
- }
-
- WriteResult result = delegate_->Set(options, values);
- if (result->HasError()) {
- return result.Pass();
- }
-
- used_total_ = new_used_total;
- used_per_setting_ = new_used_per_setting;
- return result.Pass();
-}
-
-ValueStore::WriteResult SettingsStorageQuotaEnforcer::Remove(
- const std::string& key) {
- WriteResult result = delegate_->Remove(key);
- if (result->HasError()) {
- return result.Pass();
- }
- Free(&used_total_, &used_per_setting_, key);
- return result.Pass();
-}
-
-ValueStore::WriteResult SettingsStorageQuotaEnforcer::Remove(
- const std::vector<std::string>& keys) {
- WriteResult result = delegate_->Remove(keys);
- if (result->HasError()) {
- return result.Pass();
- }
-
- for (std::vector<std::string>::const_iterator it = keys.begin();
- it != keys.end(); ++it) {
- Free(&used_total_, &used_per_setting_, *it);
- }
- return result.Pass();
-}
-
-ValueStore::WriteResult SettingsStorageQuotaEnforcer::Clear() {
- WriteResult result = delegate_->Clear();
- if (result->HasError()) {
- return result.Pass();
- }
-
- 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

Powered by Google App Engine
This is Rietveld 408576698