| Index: content/browser/indexed_db/indexed_db_active_blob_registry.cc
|
| diff --git a/content/browser/indexed_db/indexed_db_active_blob_registry.cc b/content/browser/indexed_db/indexed_db_active_blob_registry.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0feb18a4d406cd2d5247974bc07c7e8ccf1e40d9
|
| --- /dev/null
|
| +++ b/content/browser/indexed_db/indexed_db_active_blob_registry.cc
|
| @@ -0,0 +1,139 @@
|
| +// Copyright (c) 2013 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 "base/bind.h"
|
| +#include "base/location.h"
|
| +#include "base/task_runner.h"
|
| +#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
|
| +#include "content/browser/indexed_db/indexed_db_backing_store.h"
|
| +#include "content/browser/indexed_db/indexed_db_factory.h"
|
| +#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
|
| +
|
| +namespace content {
|
| +
|
| +IndexedDBActiveBlobRegistry::IndexedDBActiveBlobRegistry(
|
| + IndexedDBBackingStore* backing_store)
|
| + : backing_store_(backing_store),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +IndexedDBActiveBlobRegistry::~IndexedDBActiveBlobRegistry() {
|
| + DCHECK(use_tracker_.empty());
|
| +}
|
| +
|
| +void IndexedDBActiveBlobRegistry::AddBlobRef(
|
| + int64 database_id, int64 blob_key) {
|
| + DCHECK(backing_store_->task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
|
| + DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
|
| + DCHECK(deleted_dbs_.end() == deleted_dbs_.find(database_id));
|
| + bool need_ref = use_tracker_.empty();
|
| + SingleDBMap& single_db_map = use_tracker_[database_id];
|
| + SingleDBMap::iterator iter = single_db_map.find(blob_key);
|
| + if (iter == single_db_map.end()) {
|
| + single_db_map[blob_key] = false;
|
| + if (need_ref)
|
| + backing_store_->factory()->ReportOutstandingBlobs(
|
| + backing_store_->origin_url(), true);
|
| + } else {
|
| + DCHECK(!need_ref);
|
| + DCHECK(!iter->second); // You can't add a reference once it's been deleted.
|
| + }
|
| +}
|
| +
|
| +void IndexedDBActiveBlobRegistry::ReleaseBlobRef(
|
| + int64 database_id, int64 blob_key) {
|
| + DCHECK(backing_store_->task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
|
| + DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
|
| + AllDBsMap::iterator db_pair = use_tracker_.find(database_id);
|
| + if (db_pair == use_tracker_.end()) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| + SingleDBMap& single_db = db_pair->second;
|
| + SingleDBMap::iterator blob_pair = single_db.find(blob_key);
|
| + if (blob_pair == single_db.end()) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| + bool delete_in_backend = false;
|
| + DeletedDBSet::iterator db_to_delete = deleted_dbs_.find(database_id);
|
| + bool db_marked_for_deletion = db_to_delete != deleted_dbs_.end();
|
| + // Don't bother deleting the file if we're going to delete its whole
|
| + // database directory soon.
|
| + delete_in_backend = blob_pair->second && !db_marked_for_deletion;
|
| + single_db.erase(blob_pair);
|
| + if (single_db.empty()) {
|
| + use_tracker_.erase(db_pair);
|
| + if (db_marked_for_deletion) {
|
| + delete_in_backend = true;
|
| + blob_key = DatabaseMetaDataKey::kAllBlobsKey;
|
| + deleted_dbs_.erase(db_to_delete);
|
| + }
|
| + }
|
| + if (delete_in_backend)
|
| + backing_store_->ReportBlobUnused(database_id, blob_key);
|
| + if (use_tracker_.empty())
|
| + backing_store_->factory()->ReportOutstandingBlobs(
|
| + backing_store_->origin_url(), false);
|
| +}
|
| +
|
| +bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(
|
| + int64 database_id, int64 blob_key) {
|
| + DCHECK(backing_store_->task_runner()->RunsTasksOnCurrentThread());
|
| + DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
|
| + AllDBsMap::iterator db_pair = use_tracker_.find(database_id);
|
| + if (db_pair == use_tracker_.end())
|
| + return false;
|
| +
|
| + if (blob_key == DatabaseMetaDataKey::kAllBlobsKey) {
|
| + deleted_dbs_.insert(database_id);
|
| + return true;
|
| + }
|
| +
|
| + SingleDBMap& single_db = db_pair->second;
|
| + SingleDBMap::iterator iter = single_db.find(blob_key);
|
| + if (iter == single_db.end())
|
| + return false;
|
| +
|
| + iter->second = true;
|
| + return true;
|
| +}
|
| +
|
| +void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe(
|
| + scoped_refptr<base::TaskRunner> task_runner,
|
| + base::WeakPtr<IndexedDBActiveBlobRegistry> weak_ptr, int64 database_id,
|
| + int64 blob_key, const base::FilePath& unused) {
|
| + task_runner->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &IndexedDBActiveBlobRegistry::ReleaseBlobRef, weak_ptr,
|
| + database_id, blob_key));
|
| +}
|
| +
|
| +webkit_blob::ShareableFileReference::FinalReleaseCallback
|
| +IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(
|
| + int64 database_id, int64 blob_key) {
|
| + return base::Bind(
|
| + &IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe,
|
| + scoped_refptr<base::TaskRunner>(backing_store_->task_runner()),
|
| + weak_factory_.GetWeakPtr(), database_id, blob_key);
|
| +}
|
| +
|
| +base::Closure IndexedDBActiveBlobRegistry::GetAddBlobRefCallback(
|
| + int64 database_id, int64 blob_key) {
|
| + return base::Bind(
|
| + &IndexedDBActiveBlobRegistry::AddBlobRef,
|
| + weak_factory_.GetWeakPtr(), database_id, blob_key);
|
| +}
|
| +
|
| +void IndexedDBActiveBlobRegistry::ForceShutdown() {
|
| + weak_factory_.InvalidateWeakPtrs();
|
| + if (!use_tracker_.empty()) {
|
| + use_tracker_.clear();
|
| + }
|
| +}
|
| +
|
| +} // namespace content
|
|
|