summaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
authordmurph <dmurph@chromium.org>2015-10-14 10:25:28 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-14 17:26:21 +0000
commitd0e06a58f51ee83a670829425cd65a5693909eee (patch)
tree16ed4f48a84e6c4fe8382d2d638fc01182245db9 /storage
parent7c4128b0865b0cf6dad79465f05a86882087b697 (diff)
downloadchromium_src-d0e06a58f51ee83a670829425cd65a5693909eee.zip
chromium_src-d0e06a58f51ee83a670829425cd65a5693909eee.tar.gz
chromium_src-d0e06a58f51ee83a670829425cd65a5693909eee.tar.bz2
[BlobAsync] Patch 1: BlobStorageRegistry
Note: This patch is a no-op, and will be hooked up in a later patch. Patches: 1: https://codereview.chromium.org/1287303002 2: https://codereview.chromium.org/1288373002 3: https://codereview.chromium.org/1292523002 4: https://codereview.chromium.org/1098853003 Hookup: https://codereview.chromium.org/1234813004 BUG=375297 Review URL: https://codereview.chromium.org/1287303002 Cr-Commit-Position: refs/heads/master@{#354050}
Diffstat (limited to 'storage')
-rw-r--r--storage/browser/BUILD.gn2
-rw-r--r--storage/browser/blob/blob_storage_registry.cc116
-rw-r--r--storage/browser/blob/blob_storage_registry.h108
-rw-r--r--storage/browser/blob/internal_blob_data.h1
-rw-r--r--storage/storage_browser.gyp2
5 files changed, 229 insertions, 0 deletions
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn
index 6206f37..e3bfa81 100644
--- a/storage/browser/BUILD.gn
+++ b/storage/browser/BUILD.gn
@@ -18,6 +18,8 @@ component("browser") {
"blob/blob_reader.h",
"blob/blob_storage_context.cc",
"blob/blob_storage_context.h",
+ "blob/blob_storage_registry.cc",
+ "blob/blob_storage_registry.h",
"blob/blob_url_request_job.cc",
"blob/blob_url_request_job.h",
"blob/blob_url_request_job_factory.cc",
diff --git a/storage/browser/blob/blob_storage_registry.cc b/storage/browser/blob/blob_storage_registry.cc
new file mode 100644
index 0000000..805a677d
--- /dev/null
+++ b/storage/browser/blob/blob_storage_registry.cc
@@ -0,0 +1,116 @@
+// Copyright 2015 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 "storage/browser/blob/blob_storage_registry.h"
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/stl_util.h"
+#include "url/gurl.h"
+
+namespace storage {
+using BlobState = BlobStorageRegistry::BlobState;
+
+namespace {
+// We can't use GURL directly for these hash fragment manipulations
+// since it doesn't have specific knowlege of the BlobURL format. GURL
+// treats BlobURLs as if they were PathURLs which don't support hash
+// fragments.
+
+bool BlobUrlHasRef(const GURL& url) {
+ return url.spec().find('#') != std::string::npos;
+}
+
+GURL ClearBlobUrlRef(const GURL& url) {
+ size_t hash_pos = url.spec().find('#');
+ if (hash_pos == std::string::npos)
+ return url;
+ return GURL(url.spec().substr(0, hash_pos));
+}
+
+} // namespace
+
+BlobStorageRegistry::Entry::Entry(int refcount, BlobState state)
+ : refcount(refcount), state(state), exceeded_memory(false) {}
+
+BlobStorageRegistry::Entry::~Entry() {}
+
+bool BlobStorageRegistry::Entry::TestAndSetState(BlobState expected,
+ BlobState set) {
+ if (state != expected)
+ return false;
+ state = set;
+ return true;
+}
+
+BlobStorageRegistry::BlobStorageRegistry() {}
+
+BlobStorageRegistry::~BlobStorageRegistry() {
+ // Note: We don't bother calling the construction complete callbacks, as we
+ // are only being destructed at the end of the life of the browser process.
+ // So it shouldn't matter.
+}
+
+BlobStorageRegistry::Entry* BlobStorageRegistry::CreateEntry(
+ const std::string& uuid) {
+ DCHECK(!ContainsKey(blob_map_, uuid));
+ Entry* entry = new Entry(1, BlobState::RESERVED);
+ blob_map_.add(uuid, make_scoped_ptr(entry));
+ return entry;
+}
+
+bool BlobStorageRegistry::DeleteEntry(const std::string& uuid) {
+ return blob_map_.erase(uuid) == 1;
+}
+
+BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntry(
+ const std::string& uuid) {
+ BlobMap::iterator found = blob_map_.find(uuid);
+ if (found == blob_map_.end())
+ return nullptr;
+ return found->second;
+}
+
+bool BlobStorageRegistry::CreateUrlMapping(const GURL& blob_url,
+ const std::string& uuid) {
+ DCHECK(!BlobUrlHasRef(blob_url));
+ if (blob_map_.find(uuid) == blob_map_.end() || IsURLMapped(blob_url))
+ return false;
+ url_to_uuid_[blob_url] = uuid;
+ return true;
+}
+
+bool BlobStorageRegistry::DeleteURLMapping(const GURL& blob_url,
+ std::string* uuid) {
+ DCHECK(!BlobUrlHasRef(blob_url));
+ URLMap::iterator found = url_to_uuid_.find(blob_url);
+ if (found == url_to_uuid_.end())
+ return false;
+ if (uuid)
+ uuid->assign(found->second);
+ url_to_uuid_.erase(found);
+ return true;
+}
+
+bool BlobStorageRegistry::IsURLMapped(const GURL& blob_url) const {
+ return ContainsKey(url_to_uuid_, blob_url);
+}
+
+BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntryFromURL(
+ const GURL& url,
+ std::string* uuid) {
+ URLMap::iterator found =
+ url_to_uuid_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url);
+ if (found == url_to_uuid_.end())
+ return nullptr;
+ Entry* entry = GetEntry(found->second);
+ if (entry && uuid)
+ uuid->assign(found->second);
+ return entry;
+}
+
+} // namespace storage
diff --git a/storage/browser/blob/blob_storage_registry.h b/storage/browser/blob/blob_storage_registry.h
new file mode 100644
index 0000000..8a79493
--- /dev/null
+++ b/storage/browser/blob/blob_storage_registry.h
@@ -0,0 +1,108 @@
+// Copyright 2015 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.
+
+#ifndef STORAGE_BROWSER_BLOB_BLOB_STORAGE_REGISTRY_H_
+#define STORAGE_BROWSER_BLOB_BLOB_STORAGE_REGISTRY_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/macros.h"
+#include "storage/browser/blob/internal_blob_data.h"
+#include "storage/browser/storage_browser_export.h"
+
+class GURL;
+
+namespace storage {
+
+// This class stores the blob data in the various states of construction, as
+// well as URL mappings to blob uuids.
+// Implementation notes:
+// * There is no implicit refcounting in this class, except for setting the
+// refcount to 1 on registration.
+// * When removing a uuid registration, we do not check for URL mappings to that
+// uuid. The user must keep track of these.
+class STORAGE_EXPORT BlobStorageRegistry {
+ public:
+ enum class BlobState {
+ // First the renderer reserves the uuid.
+ RESERVED = 1,
+ // Second, we are asynchronously transporting data to the browser.
+ ASYNC_TRANSPORTATION,
+ // Third, we construct the blob when we have all of the data.
+ CONSTRUCTION,
+ // Finally, the blob is built.
+ ACTIVE
+ };
+
+ struct STORAGE_EXPORT Entry {
+ size_t refcount;
+ BlobState state;
+ std::vector<base::Callback<void(bool)>> construction_complete_callbacks;
+
+ // Flags
+ bool exceeded_memory;
+
+ // data and data_builder are mutually exclusive.
+ scoped_ptr<InternalBlobData> data;
+ scoped_ptr<InternalBlobData::Builder> data_builder;
+
+ Entry() = delete;
+ Entry(int refcount, BlobState state);
+ ~Entry();
+
+ // Performs a test-and-set on the state of the given blob. If the state
+ // isn't as expected, we return false. Otherwise we set the new state and
+ // return true.
+ bool TestAndSetState(BlobState expected, BlobState set);
+ };
+
+ BlobStorageRegistry();
+ ~BlobStorageRegistry();
+
+ // Creates the blob entry with a refcount of 1 and a state of RESERVED. If
+ // the blob is already in use, we return null.
+ Entry* CreateEntry(const std::string& uuid);
+
+ // Removes the blob entry with the given uuid. This does not unmap any
+ // URLs that are pointing to this uuid. Returns if the entry existed.
+ bool DeleteEntry(const std::string& uuid);
+
+ // Gets the blob entry for the given uuid. Returns nullptr if the entry
+ // does not exist.
+ Entry* GetEntry(const std::string& uuid);
+
+ // Creates a url mapping from blob uuid to the given url. Returns false if
+ // the uuid isn't mapped to an entry or if there already is a map for the URL.
+ bool CreateUrlMapping(const GURL& url, const std::string& uuid);
+
+ // Removes the given URL mapping. Optionally populates a uuid string of the
+ // removed entry uuid. Returns false if the url isn't mapped.
+ bool DeleteURLMapping(const GURL& url, std::string* uuid);
+
+ // Returns if the url is mapped to a blob uuid.
+ bool IsURLMapped(const GURL& blob_url) const;
+
+ // Returns the entry from the given url, and optionally populates the uuid for
+ // that entry. Returns a nullptr if the mapping or entry doesn't exist.
+ Entry* GetEntryFromURL(const GURL& url, std::string* uuid);
+
+ size_t blob_count() const { return blob_map_.size(); }
+ size_t url_count() const { return url_to_uuid_.size(); }
+
+ private:
+ using BlobMap = base::ScopedPtrHashMap<std::string, scoped_ptr<Entry>>;
+ using URLMap = std::map<GURL, std::string>;
+
+ BlobMap blob_map_;
+ URLMap url_to_uuid_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlobStorageRegistry);
+};
+
+} // namespace storage
+#endif // STORAGE_BROWSER_BLOB_BLOB_STORAGE_REGISTRY_H_
diff --git a/storage/browser/blob/internal_blob_data.h b/storage/browser/blob/internal_blob_data.h
index aa47101..7ec2bf8 100644
--- a/storage/browser/blob/internal_blob_data.h
+++ b/storage/browser/blob/internal_blob_data.h
@@ -23,6 +23,7 @@ class InternalBlobData {
protected:
friend class BlobStorageContext;
+ friend class BlobStorageRegistry;
friend class ViewBlobInternalsJob;
// Removes the given blob uuid from the internal ShareableBlobDataItems.
diff --git a/storage/storage_browser.gyp b/storage/storage_browser.gyp
index de1d166..3f4b7ea 100644
--- a/storage/storage_browser.gyp
+++ b/storage/storage_browser.gyp
@@ -37,6 +37,8 @@
'browser/blob/blob_reader.h',
'browser/blob/blob_storage_context.cc',
'browser/blob/blob_storage_context.h',
+ 'browser/blob/blob_storage_registry.cc',
+ 'browser/blob/blob_storage_registry.h',
'browser/blob/blob_url_request_job.cc',
'browser/blob/blob_url_request_job.h',
'browser/blob/blob_url_request_job_factory.cc',