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

Unified Diff: webkit/dom_storage/dom_storage_cached_area.cc

Issue 10383123: Switch to using the async DomStorage IPC messages and add a caching layer … (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 7 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/dom_storage/dom_storage_cached_area.cc
===================================================================
--- webkit/dom_storage/dom_storage_cached_area.cc (revision 0)
+++ webkit/dom_storage/dom_storage_cached_area.cc (revision 0)
@@ -0,0 +1,190 @@
+// 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/dom_storage/dom_storage_cached_area.h"
+
+#include "base/basictypes.h"
+#include "webkit/dom_storage/dom_storage_map.h"
+#include "webkit/dom_storage/dom_storage_proxy.h"
+
+namespace dom_storage {
+
+DomStorageCachedArea::DomStorageCachedArea(
+ int64 namespace_id, const GURL& origin, DomStorageProxy* proxy)
+ : namespace_id_(namespace_id), origin_(origin),
+ proxy_(proxy), weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ ignore_all_mutations_(false) {
+}
+
+DomStorageCachedArea::~DomStorageCachedArea() {
+}
+
+unsigned DomStorageCachedArea::GetLength(int connection_id) {
+ PrimeIfNeeded(connection_id);
+ return map_->Length();
+}
+
+NullableString16 DomStorageCachedArea::GetKey(
+ int connection_id, unsigned index) {
+ PrimeIfNeeded(connection_id);
+ return map_->Key(index);
+}
+
+NullableString16 DomStorageCachedArea::GetItem(
+ int connection_id, const string16& key) {
+ PrimeIfNeeded(connection_id);
+ return map_->GetItem(key);
+}
+
+bool DomStorageCachedArea::SetItem(
+ int connection_id, const string16& key,
+ const string16& value, const GURL& page_url) {
+ // A quick check to reject obvsiously overbudget items to avoid
ericu 2012/05/22 23:23:35 Typo: obviously.
michaeln 2012/05/23 22:37:28 Done.
+ // the priming the cache.
+ if (key.length() + value.length() > dom_storage::kPerAreaQuota)
+ return false;
+
+ PrimeIfNeeded(connection_id);
+ NullableString16 unused;
+ if (!map_->SetItem(key, value, &unused))
+ return false;
+
+ // Ignore mutations to 'key' until OnSetItemComplete.
+ ignore_key_mutations_[key]++;
+ proxy_->SetItem(
+ connection_id, key, value, page_url,
+ base::Bind(&DomStorageCachedArea::OnSetItemComplete,
+ weak_factory_.GetWeakPtr(), key));
+ return true;
+}
+
+void DomStorageCachedArea::RemoveItem(
+ int connection_id, const string16& key, const GURL& page_url) {
+ PrimeIfNeeded(connection_id);
+ string16 unused;
+ if (!map_->RemoveItem(key, &unused))
+ return;
+
+ // Ignore mutations to 'key' until OnRemoveItemComplete.
+ ignore_key_mutations_[key]++;
+ proxy_->RemoveItem(
+ connection_id, key, page_url,
+ base::Bind(&DomStorageCachedArea::OnRemoveItemComplete,
+ weak_factory_.GetWeakPtr(), key));
+}
+
+void DomStorageCachedArea::Clear(int connection_id, const GURL& page_url) {
+ // No need to prime the cache in this case.
+ Reset();
+ map_ = new DomStorageMap(dom_storage::kPerAreaQuota);
+
+ // Ignore all mutations until OnClearComplete time.
+ ignore_all_mutations_ = true;
ericu 2012/05/22 23:23:35 What if we call clear twice before the first OnCle
michaeln 2012/05/23 00:38:51 Reset() kills all pending callbacks by virtue of i
+ proxy_->ClearArea(
+ connection_id, page_url,
+ base::Bind(&DomStorageCachedArea::OnClearComplete,
+ weak_factory_.GetWeakPtr()));
+}
+
+void DomStorageCachedArea::ApplyMutation(
+ const NullableString16& key, const NullableString16& old_value,
+ const NullableString16& new_value) {
+ if (!map_ || ignore_all_mutations_)
+ return;
+
+ if (key.is_null()) {
+ // It's a clear event.
+ scoped_refptr<DomStorageMap> old = map_;
+ map_ = new DomStorageMap(dom_storage::kPerAreaQuota);
+
+ // We have to retain local additions which happened after this
+ // clear operation from another process.
+ std::map<string16, int>::iterator iter = ignore_key_mutations_.begin();
+ while (iter != ignore_key_mutations_.end()) {
+ NullableString16 value = old->GetItem(iter->first);
+ if (!value.is_null()) {
+ NullableString16 unused;
+ map_->SetItem(iter->first, value.string(), &unused);
+ }
+ ++iter;
+ }
+ return;
+ }
+
+ // We have to retain local changes.
+ if (ignore_key_mutations_.find(key.string()) != ignore_key_mutations_.end())
+ return;
+
+ if (new_value.is_null()) {
+ string16 unused;
+ map_->RemoveItem(key.string(), &unused);
+ } else {
+ // We turn off quota checking here to accomodate the over budget allowance
+ // that's provided in the browser process.
+ NullableString16 unused;
+ map_->set_quota(kint32max);
+ map_->SetItem(key.string(), new_value.string(), &unused);
+ map_->set_quota(dom_storage::kPerAreaQuota);
+ }
+}
+
+void DomStorageCachedArea::Prime(int connection_id) {
+ DCHECK(!map_);
+
+ // The LoadArea method is actually synchronous, but we have to
+ // wait for an asyncly delivered message to know when incoming
+ // mutation events should be applied. Our valuemap is plucked
+ // from ipc stream out of order, mutations in front if it need
+ // to be ignored.
+
+ // Ignore all mutations until OnLoadComplete time.
+ ignore_all_mutations_ = true;
+ ValuesMap values;
+ proxy_->LoadArea(
+ connection_id, &values,
+ base::Bind(&DomStorageCachedArea::OnLoadComplete,
+ weak_factory_.GetWeakPtr()));
+ map_ = new DomStorageMap(dom_storage::kPerAreaQuota);
+ map_->SwapValues(&values);
+}
+
+void DomStorageCachedArea::OnLoadComplete(bool success) {
+ DCHECK(success);
+ ignore_all_mutations_ = false;
ericu 2012/05/22 23:23:35 Here, too, what if we called clear before this cam
michaeln 2012/05/23 00:38:51 If we called clear before this came back... it wil
+}
+
+void DomStorageCachedArea::OnSetItemComplete(
+ const string16& key, bool success) {
+ if (!success) {
+ Reset();
+ return;
+ }
+ std::map<string16, int>::iterator found = ignore_key_mutations_.find(key);
+ DCHECK(found != ignore_key_mutations_.end());
+ if (--found->second == 0)
+ ignore_key_mutations_.erase(found);
+}
+
+void DomStorageCachedArea::OnRemoveItemComplete(
+ const string16& key, bool success) {
+ DCHECK(success);
+ std::map<string16, int>::iterator found = ignore_key_mutations_.find(key);
+ DCHECK(found != ignore_key_mutations_.end());
+ if (--found->second == 0)
+ ignore_key_mutations_.erase(found);
+}
+
+void DomStorageCachedArea::OnClearComplete(bool success) {
+ DCHECK(success);
+ ignore_all_mutations_ = false;
+}
+
+void DomStorageCachedArea::Reset() {
+ map_ = NULL;
+ weak_factory_.InvalidateWeakPtrs();
+ ignore_key_mutations_.clear();
+ ignore_all_mutations_ = false;
+}
+
+} // namespace dom_storage
Property changes on: webkit\dom_storage\dom_storage_cached_area.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698