Index: webkit/dom_storage/dom_storage_context.cc |
diff --git a/webkit/dom_storage/dom_storage_context.cc b/webkit/dom_storage/dom_storage_context.cc |
index 45aae747639668a2513e63450d27ca46a8f0064e..0fe4b3ac66e803296fb8282d5fcb90f7df2a3043 100644 |
--- a/webkit/dom_storage/dom_storage_context.cc |
+++ b/webkit/dom_storage/dom_storage_context.cc |
@@ -12,6 +12,7 @@ |
#include "base/time.h" |
#include "webkit/dom_storage/dom_storage_area.h" |
#include "webkit/dom_storage/dom_storage_database.h" |
+#include "webkit/dom_storage/dom_storage_host.h" |
#include "webkit/dom_storage/dom_storage_namespace.h" |
#include "webkit/dom_storage/dom_storage_task_runner.h" |
#include "webkit/dom_storage/dom_storage_types.h" |
@@ -35,7 +36,8 @@ DomStorageContext::DomStorageContext( |
is_shutdown_(false), |
force_keep_session_state_(false), |
special_storage_policy_(special_storage_policy), |
- scavenging_started_(false) { |
+ scavenging_started_(false), |
+ total_area_size_(-1) { |
// AtomicSequenceNum starts at 0 but we want to start session |
// namespace ids at one since zero is reserved for the |
// kLocalStorageNamespaceId. |
@@ -214,6 +216,7 @@ void DomStorageContext::NotifyItemSet( |
const string16& new_value, |
const NullableString16& old_value, |
const GURL& page_url) { |
+ InvalidateInMemoryAreaSize(); |
FOR_EACH_OBSERVER( |
EventObserver, event_observers_, |
OnDomStorageItemSet(area, key, new_value, old_value, page_url)); |
@@ -224,6 +227,7 @@ void DomStorageContext::NotifyItemRemoved( |
const string16& key, |
const string16& old_value, |
const GURL& page_url) { |
+ InvalidateInMemoryAreaSize(); |
FOR_EACH_OBSERVER( |
EventObserver, event_observers_, |
OnDomStorageItemRemoved(area, key, old_value, page_url)); |
@@ -232,6 +236,7 @@ void DomStorageContext::NotifyItemRemoved( |
void DomStorageContext::NotifyAreaCleared( |
const DomStorageArea* area, |
const GURL& page_url) { |
+ InvalidateInMemoryAreaSize(); |
FOR_EACH_OBSERVER( |
EventObserver, event_observers_, |
OnDomStorageAreaCleared(area, page_url)); |
@@ -352,6 +357,26 @@ void DomStorageContext::StartScavengingUnusedSessionStorage() { |
} |
} |
+bool DomStorageContext::CanSetItem( |
+ DomStorageHost* host, |
+ int connection_id, |
+ const string16& key, |
+ const string16& value) { |
+ DCHECK(host); |
+ if (GetRemainingCacheSize() >= static_cast<int64>(kPerAreaQuota)) |
+ return true; |
+ // Go through the slower check only if the memory is getting tight. |
+ // TODO(kinuko,michaeln): Purge cache memory if we're caching too many areas. |
+ NullableString16 old_value = host->GetAreaItem(connection_id, key); |
+ int64 increase = value.size(); |
+ if (old_value.is_null()) |
+ increase += key.size(); |
+ else |
+ increase -= old_value.string().size(); |
+ return static_cast<int64>(increase * sizeof(char16)) <= |
+ GetRemainingCacheSize(); |
+} |
+ |
void DomStorageContext::FindUnusedNamespaces() { |
DCHECK(session_storage_database_.get()); |
if (scavenging_started_) |
@@ -421,4 +446,25 @@ void DomStorageContext::DeleteNextUnusedNamespaceInCommitSequence() { |
} |
} |
+int64 DomStorageContext::GetRemainingCacheSize() { |
+ if (total_area_size_ < 0) { |
Mike West
2013/03/06 13:41:11
I don't see where you're updating total_area_size_
|
+ total_area_size_ = 0; |
+ // Naively add-up the area size for each connection. |
+ std::set<DomStorageArea*> visited_areas; |
+ for (StorageNamespaceMap::const_iterator itr = namespaces_.begin(); |
+ itr != namespaces_.end(); ++itr) { |
+ const DomStorageNamespace::AreaMap& map = itr->second->GetAreaMap(); |
+ for (DomStorageNamespace::AreaMap::const_iterator map_itr = map.begin(); |
+ map_itr != map.end(); ++map_itr) { |
+ // We don't care open_count_ here, since we don't purge memory (yet). |
+ DomStorageArea* area = map_itr->second.area_; |
+ DCHECK(area); |
+ if (visited_areas.insert(area).second) |
+ total_area_size_ += area->GetMapSize(); |
+ } |
+ } |
+ } |
+ return kMaxInMemoryAreaSize - total_area_size_; |
+} |
+ |
} // namespace dom_storage |