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

Unified Diff: webkit/browser/dom_storage/dom_storage_area.cc

Issue 22297005: Move webkit/{browser,common}/dom_storage into content/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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: webkit/browser/dom_storage/dom_storage_area.cc
diff --git a/webkit/browser/dom_storage/dom_storage_area.cc b/webkit/browser/dom_storage/dom_storage_area.cc
deleted file mode 100644
index d0e2ac3efd28625352467c12dce3b5bd5304211b..0000000000000000000000000000000000000000
--- a/webkit/browser/dom_storage/dom_storage_area.cc
+++ /dev/null
@@ -1,396 +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 "webkit/browser/dom_storage/dom_storage_area.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "webkit/browser/database/database_util.h"
-#include "webkit/browser/dom_storage/dom_storage_namespace.h"
-#include "webkit/browser/dom_storage/dom_storage_task_runner.h"
-#include "webkit/browser/dom_storage/local_storage_database_adapter.h"
-#include "webkit/browser/dom_storage/session_storage_database.h"
-#include "webkit/browser/dom_storage/session_storage_database_adapter.h"
-#include "webkit/common/database/database_identifier.h"
-#include "webkit/common/dom_storage/dom_storage_map.h"
-#include "webkit/common/dom_storage/dom_storage_types.h"
-#include "webkit/common/fileapi/file_system_util.h"
-
-using webkit_database::DatabaseUtil;
-
-namespace dom_storage {
-
-static const int kCommitTimerSeconds = 1;
-
-DomStorageArea::CommitBatch::CommitBatch()
- : clear_all_first(false) {
-}
-DomStorageArea::CommitBatch::~CommitBatch() {}
-
-
-// static
-const base::FilePath::CharType DomStorageArea::kDatabaseFileExtension[] =
- FILE_PATH_LITERAL(".localstorage");
-
-// static
-base::FilePath DomStorageArea::DatabaseFileNameFromOrigin(const GURL& origin) {
- std::string filename = webkit_database::GetIdentifierFromOrigin(origin);
- // There is no base::FilePath.AppendExtension() method, so start with just the
- // extension as the filename, and then InsertBeforeExtension the desired
- // name.
- return base::FilePath().Append(kDatabaseFileExtension).
- InsertBeforeExtensionASCII(filename);
-}
-
-// static
-GURL DomStorageArea::OriginFromDatabaseFileName(const base::FilePath& name) {
- DCHECK(name.MatchesExtension(kDatabaseFileExtension));
- std::string origin_id =
- name.BaseName().RemoveExtension().MaybeAsASCII();
- return webkit_database::GetOriginFromIdentifier(origin_id);
-}
-
-DomStorageArea::DomStorageArea(const GURL& origin, const base::FilePath& directory,
- DomStorageTaskRunner* task_runner)
- : namespace_id_(kLocalStorageNamespaceId), origin_(origin),
- directory_(directory),
- task_runner_(task_runner),
- map_(new DomStorageMap(kPerAreaQuota + kPerAreaOverQuotaAllowance)),
- is_initial_import_done_(true),
- is_shutdown_(false),
- commit_batches_in_flight_(0) {
- if (!directory.empty()) {
- base::FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_));
- backing_.reset(new LocalStorageDatabaseAdapter(path));
- is_initial_import_done_ = false;
- }
-}
-
-DomStorageArea::DomStorageArea(
- int64 namespace_id,
- const std::string& persistent_namespace_id,
- const GURL& origin,
- SessionStorageDatabase* session_storage_backing,
- DomStorageTaskRunner* task_runner)
- : namespace_id_(namespace_id),
- persistent_namespace_id_(persistent_namespace_id),
- origin_(origin),
- task_runner_(task_runner),
- map_(new DomStorageMap(kPerAreaQuota + kPerAreaOverQuotaAllowance)),
- session_storage_backing_(session_storage_backing),
- is_initial_import_done_(true),
- is_shutdown_(false),
- commit_batches_in_flight_(0) {
- DCHECK(namespace_id != kLocalStorageNamespaceId);
- if (session_storage_backing) {
- backing_.reset(new SessionStorageDatabaseAdapter(
- session_storage_backing, persistent_namespace_id, origin));
- is_initial_import_done_ = false;
- }
-}
-
-DomStorageArea::~DomStorageArea() {
-}
-
-void DomStorageArea::ExtractValues(ValuesMap* map) {
- if (is_shutdown_)
- return;
- InitialImportIfNeeded();
- map_->ExtractValues(map);
-}
-
-unsigned DomStorageArea::Length() {
- if (is_shutdown_)
- return 0;
- InitialImportIfNeeded();
- return map_->Length();
-}
-
-base::NullableString16 DomStorageArea::Key(unsigned index) {
- if (is_shutdown_)
- return base::NullableString16();
- InitialImportIfNeeded();
- return map_->Key(index);
-}
-
-base::NullableString16 DomStorageArea::GetItem(const base::string16& key) {
- if (is_shutdown_)
- return base::NullableString16();
- InitialImportIfNeeded();
- return map_->GetItem(key);
-}
-
-bool DomStorageArea::SetItem(const base::string16& key,
- const base::string16& value,
- base::NullableString16* old_value) {
- if (is_shutdown_)
- return false;
- InitialImportIfNeeded();
- if (!map_->HasOneRef())
- map_ = map_->DeepCopy();
- bool success = map_->SetItem(key, value, old_value);
- if (success && backing_) {
- CommitBatch* commit_batch = CreateCommitBatchIfNeeded();
- commit_batch->changed_values[key] = base::NullableString16(value, false);
- }
- return success;
-}
-
-bool DomStorageArea::RemoveItem(const base::string16& key,
- base::string16* old_value) {
- if (is_shutdown_)
- return false;
- InitialImportIfNeeded();
- if (!map_->HasOneRef())
- map_ = map_->DeepCopy();
- bool success = map_->RemoveItem(key, old_value);
- if (success && backing_) {
- CommitBatch* commit_batch = CreateCommitBatchIfNeeded();
- commit_batch->changed_values[key] = base::NullableString16();
- }
- return success;
-}
-
-bool DomStorageArea::Clear() {
- if (is_shutdown_)
- return false;
- InitialImportIfNeeded();
- if (map_->Length() == 0)
- return false;
-
- map_ = new DomStorageMap(kPerAreaQuota + kPerAreaOverQuotaAllowance);
-
- if (backing_) {
- CommitBatch* commit_batch = CreateCommitBatchIfNeeded();
- commit_batch->clear_all_first = true;
- commit_batch->changed_values.clear();
- }
-
- return true;
-}
-
-void DomStorageArea::FastClear() {
- // TODO(marja): Unify clearing localStorage and sessionStorage. The problem is
- // to make the following 3 to work together: 1) FastClear, 2) PurgeMemory and
- // 3) not creating events when clearing an empty area.
- if (is_shutdown_)
- return;
-
- map_ = new DomStorageMap(kPerAreaQuota + kPerAreaOverQuotaAllowance);
- // This ensures no import will happen while we're waiting to clear the data
- // from the database. This mechanism fails if PurgeMemory is called.
- is_initial_import_done_ = true;
-
- if (backing_) {
- CommitBatch* commit_batch = CreateCommitBatchIfNeeded();
- commit_batch->clear_all_first = true;
- commit_batch->changed_values.clear();
- }
-}
-
-DomStorageArea* DomStorageArea::ShallowCopy(
- int64 destination_namespace_id,
- const std::string& destination_persistent_namespace_id) {
- DCHECK_NE(kLocalStorageNamespaceId, namespace_id_);
- DCHECK_NE(kLocalStorageNamespaceId, destination_namespace_id);
-
- DomStorageArea* copy = new DomStorageArea(
- destination_namespace_id, destination_persistent_namespace_id, origin_,
- session_storage_backing_.get(), task_runner_.get());
- copy->map_ = map_;
- copy->is_shutdown_ = is_shutdown_;
- copy->is_initial_import_done_ = true;
-
- // All the uncommitted changes to this area need to happen before the actual
- // shallow copy is made (scheduled by the upper layer). Another OnCommitTimer
- // call might be in the event queue at this point, but it's handled gracefully
- // when it fires.
- if (commit_batch_)
- OnCommitTimer();
- return copy;
-}
-
-bool DomStorageArea::HasUncommittedChanges() const {
- DCHECK(!is_shutdown_);
- return commit_batch_.get() || commit_batches_in_flight_;
-}
-
-void DomStorageArea::DeleteOrigin() {
- DCHECK(!is_shutdown_);
- // This function shouldn't be called for sessionStorage.
- DCHECK(!session_storage_backing_.get());
- if (HasUncommittedChanges()) {
- // TODO(michaeln): This logically deletes the data immediately,
- // and in a matter of a second, deletes the rows from the backing
- // database file, but the file itself will linger until shutdown
- // or purge time. Ideally, this should delete the file more
- // quickly.
- Clear();
- return;
- }
- map_ = new DomStorageMap(kPerAreaQuota + kPerAreaOverQuotaAllowance);
- if (backing_) {
- is_initial_import_done_ = false;
- backing_->Reset();
- backing_->DeleteFiles();
- }
-}
-
-void DomStorageArea::PurgeMemory() {
- DCHECK(!is_shutdown_);
- // Purging sessionStorage is not supported; it won't work with FastClear.
- DCHECK(!session_storage_backing_.get());
- if (!is_initial_import_done_ || // We're not using any memory.
- !backing_.get() || // We can't purge anything.
- HasUncommittedChanges()) // We leave things alone with changes pending.
- return;
-
- // Drop the in memory cache, we'll reload when needed.
- is_initial_import_done_ = false;
- map_ = new DomStorageMap(kPerAreaQuota + kPerAreaOverQuotaAllowance);
-
- // Recreate the database object, this frees up the open sqlite connection
- // and its page cache.
- backing_->Reset();
-}
-
-void DomStorageArea::Shutdown() {
- DCHECK(!is_shutdown_);
- is_shutdown_ = true;
- map_ = NULL;
- if (!backing_)
- return;
-
- bool success = task_runner_->PostShutdownBlockingTask(
- FROM_HERE,
- DomStorageTaskRunner::COMMIT_SEQUENCE,
- base::Bind(&DomStorageArea::ShutdownInCommitSequence, this));
- DCHECK(success);
-}
-
-void DomStorageArea::InitialImportIfNeeded() {
- if (is_initial_import_done_)
- return;
-
- DCHECK(backing_.get());
-
- base::TimeTicks before = base::TimeTicks::Now();
- ValuesMap initial_values;
- backing_->ReadAllValues(&initial_values);
- map_->SwapValues(&initial_values);
- is_initial_import_done_ = true;
- base::TimeDelta time_to_import = base::TimeTicks::Now() - before;
- UMA_HISTOGRAM_TIMES("LocalStorage.BrowserTimeToPrimeLocalStorage",
- time_to_import);
-
- size_t local_storage_size_kb = map_->bytes_used() / 1024;
- // Track localStorage size, from 0-6MB. Note that the maximum size should be
- // 5MB, but we add some slop since we want to make sure the max size is always
- // above what we see in practice, since histograms can't change.
- UMA_HISTOGRAM_CUSTOM_COUNTS("LocalStorage.BrowserLocalStorageSizeInKB",
- local_storage_size_kb,
- 0, 6 * 1024, 50);
- if (local_storage_size_kb < 100) {
- UMA_HISTOGRAM_TIMES(
- "LocalStorage.BrowserTimeToPrimeLocalStorageUnder100KB",
- time_to_import);
- } else if (local_storage_size_kb < 1000) {
- UMA_HISTOGRAM_TIMES(
- "LocalStorage.BrowserTimeToPrimeLocalStorage100KBTo1MB",
- time_to_import);
- } else {
- UMA_HISTOGRAM_TIMES(
- "LocalStorage.BrowserTimeToPrimeLocalStorage1MBTo5MB",
- time_to_import);
- }
-}
-
-DomStorageArea::CommitBatch* DomStorageArea::CreateCommitBatchIfNeeded() {
- DCHECK(!is_shutdown_);
- if (!commit_batch_) {
- commit_batch_.reset(new CommitBatch());
-
- // Start a timer to commit any changes that accrue in the batch, but only if
- // no commits are currently in flight. In that case the timer will be
- // started after the commits have happened.
- if (!commit_batches_in_flight_) {
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&DomStorageArea::OnCommitTimer, this),
- base::TimeDelta::FromSeconds(kCommitTimerSeconds));
- }
- }
- return commit_batch_.get();
-}
-
-void DomStorageArea::OnCommitTimer() {
- if (is_shutdown_)
- return;
-
- DCHECK(backing_.get());
-
- // It's possible that there is nothing to commit, since a shallow copy occured
- // before the timer fired.
- if (!commit_batch_)
- return;
-
- // This method executes on the primary sequence, we schedule
- // a task for immediate execution on the commit sequence.
- DCHECK(task_runner_->IsRunningOnPrimarySequence());
- bool success = task_runner_->PostShutdownBlockingTask(
- FROM_HERE,
- DomStorageTaskRunner::COMMIT_SEQUENCE,
- base::Bind(&DomStorageArea::CommitChanges, this,
- base::Owned(commit_batch_.release())));
- ++commit_batches_in_flight_;
- DCHECK(success);
-}
-
-void DomStorageArea::CommitChanges(const CommitBatch* commit_batch) {
- // This method executes on the commit sequence.
- DCHECK(task_runner_->IsRunningOnCommitSequence());
- bool success = backing_->CommitChanges(commit_batch->clear_all_first,
- commit_batch->changed_values);
- DCHECK(success); // TODO(michaeln): what if it fails?
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&DomStorageArea::OnCommitComplete, this));
-}
-
-void DomStorageArea::OnCommitComplete() {
- // We're back on the primary sequence in this method.
- DCHECK(task_runner_->IsRunningOnPrimarySequence());
- --commit_batches_in_flight_;
- if (is_shutdown_)
- return;
- if (commit_batch_.get() && !commit_batches_in_flight_) {
- // More changes have accrued, restart the timer.
- task_runner_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&DomStorageArea::OnCommitTimer, this),
- base::TimeDelta::FromSeconds(kCommitTimerSeconds));
- }
-}
-
-void DomStorageArea::ShutdownInCommitSequence() {
- // This method executes on the commit sequence.
- DCHECK(task_runner_->IsRunningOnCommitSequence());
- DCHECK(backing_.get());
- if (commit_batch_) {
- // Commit any changes that accrued prior to the timer firing.
- bool success = backing_->CommitChanges(
- commit_batch_->clear_all_first,
- commit_batch_->changed_values);
- DCHECK(success);
- }
- commit_batch_.reset();
- backing_.reset();
- session_storage_backing_ = NULL;
-}
-
-} // namespace dom_storage
« no previous file with comments | « webkit/browser/dom_storage/dom_storage_area.h ('k') | webkit/browser/dom_storage/dom_storage_area_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698