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

Unified Diff: webkit/dom_storage/session_storage_database.cc

Issue 10378066: SessionStorageDatabase: Allow writing data into a shallow copy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review. 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/session_storage_database.cc
diff --git a/webkit/dom_storage/session_storage_database.cc b/webkit/dom_storage/session_storage_database.cc
index e66d477442b9067d7bfb87b76296417023f49a48..11db6e5fbdd152c081c52751c334e26d0c6604e5 100644
--- a/webkit/dom_storage/session_storage_database.cc
+++ b/webkit/dom_storage/session_storage_database.cc
@@ -82,15 +82,15 @@ bool SessionStorageDatabase::CommitAreaChanges(int64 namespace_id,
if (!GetMapForArea(namespace_id, origin, &exists, &map_id))
return false;
if (exists) {
- // We shouldn't write data into a shallow copy. If this is a shallow copy,
- // it's a caller error (not an inconsistency in the database).
int64 ref_count;
if (!GetMapRefCount(map_id, &ref_count))
return false;
- if (!CallerErrorCheck(ref_count == 1))
- return false;
-
- if (clear_all_first) {
+ if (ref_count > 1) {
+ if (!DeepCopyArea(namespace_id, origin, !clear_all_first,
+ &map_id, &batch))
+ return false;
+ }
+ else if (clear_all_first) {
if (!ClearMap(map_id, &batch))
return false;
}
@@ -151,62 +151,6 @@ bool SessionStorageDatabase::CloneNamespace(int64 namespace_id,
return DatabaseErrorCheck(s.ok());
}
-bool SessionStorageDatabase::DeepCopyArea(int64 namespace_id,
- const GURL& origin) {
- // Example, data before deep copy:
- // | namespace-1 (1 = namespace id) | dummy |
- // | namespace-1-origin1 | 1 (mapid) |
- // | namespace-2 | dummy |
- // | namespace-2-origin1 | 1 (mapid) << references the same map
- // | map-1 | 2 (refcount) |
- // | map-1-a | b |
-
- // Example, data after deep copy copy:
- // | namespace-1 (1 = namespace id) | dummy |
- // | namespace-1-origin1 | 1 (mapid) |
- // | namespace-2 | dummy |
- // | namespace-2-origin1 | 2 (mapid) << references the new map
- // | map-1 | 1 (dec. refcount) |
- // | map-1-a | b |
- // | map-2 | 1 (refcount) |
- // | map-2-a | b |
-
- if (!LazyOpen(true))
- return false;
-
- std::string old_map_id;
- bool exists;
- if (!GetMapForArea(namespace_id, origin, &exists, &old_map_id))
- return false;
-
- // If the area doesn't exist, or if it's not a shallow copy, it's a caller
- // error.
- if (!CallerErrorCheck(exists))
- return false;
- int64 ref_count;
- if (!GetMapRefCount(old_map_id, &ref_count))
- return false;
- if (!CallerErrorCheck(ref_count > 1))
- return false;
-
- leveldb::WriteBatch batch;
- std::string new_map_id;
- if (!CreateMapForArea(namespace_id, origin, &new_map_id, &batch))
- return false;
-
- // Copy the values in the map.
- ValuesMap values;
- if (!ReadMap(old_map_id, &values, false))
- return false;
- WriteValuesToMap(new_map_id, values, &batch);
-
- if (!DecreaseMapRefCount(old_map_id, 1, &batch))
- return false;
-
- leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
- return DatabaseErrorCheck(s.ok());
-}
-
bool SessionStorageDatabase::DeleteArea(int64 namespace_id,
const GURL& origin) {
if (!LazyOpen(false)) {
@@ -603,6 +547,43 @@ bool SessionStorageDatabase::ClearMap(const std::string& map_id,
return true;
}
+bool SessionStorageDatabase::DeepCopyArea(
+ int64 namespace_id, const GURL& origin, bool copy_data,
+ std::string* map_id, leveldb::WriteBatch* batch) {
+ // Example, data before deep copy:
+ // | namespace-1 (1 = namespace id) | dummy |
+ // | namespace-1-origin1 | 1 (mapid) |
+ // | namespace-2 | dummy |
+ // | namespace-2-origin1 | 1 (mapid) << references the same map
+ // | map-1 | 2 (refcount) |
+ // | map-1-a | b |
+
+ // Example, data after deep copy copy:
+ // | namespace-1 (1 = namespace id) | dummy |
+ // | namespace-1-origin1 | 1 (mapid) |
+ // | namespace-2 | dummy |
+ // | namespace-2-origin1 | 2 (mapid) << references the new map
+ // | map-1 | 1 (dec. refcount) |
+ // | map-1-a | b |
+ // | map-2 | 1 (refcount) |
+ // | map-2-a | b |
+
+ // Read the values from the old map here. If we don't need to copy the data,
+ // this can stay empty.
+ ValuesMap values;
+ if (copy_data && !ReadMap(*map_id, &values, false))
+ return false;
+ if (!DecreaseMapRefCount(*map_id, 1, batch))
+ return false;
+ // Create a new map (this will also break the association to the old map) and
+ // write the old data into it. This will write the id of the created map into
+ // |map_id|.
+ if (!CreateMapForArea(namespace_id, origin, map_id, batch))
+ return false;
+ WriteValuesToMap(*map_id, values, batch);
+ return true;
+}
+
std::string SessionStorageDatabase::NamespaceStartKey(
const std::string& namespace_id_str) {
return base::StringPrintf("namespace-%s", namespace_id_str.c_str());
« no previous file with comments | « webkit/dom_storage/session_storage_database.h ('k') | webkit/dom_storage/session_storage_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698