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

Unified Diff: webkit/dom_storage/session_storage_database.cc

Issue 9963107: Persist sessionStorage on disk. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Draft: associate with session restore. 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 66e502f9a54be7ad6aef8da3f453fc3063f1ca2f..6661bd5a3d85b85387cc0bcc038b72269d71200e 100644
--- a/webkit/dom_storage/session_storage_database.cc
+++ b/webkit/dom_storage/session_storage_database.cc
@@ -41,7 +41,19 @@ SessionStorageDatabase::SessionStorageDatabase(const FilePath& file_path)
: file_path_(file_path),
db_error_(false),
is_inconsistent_(false),
- namespace_offset_(0) {
+ next_namespace_id_(0),
+ next_negative_namespace_id_(-1) {
+}
+
+SessionStorageDatabase::SessionStorageDatabase(
+ const FilePath& file_path,
+ const SessionStorageAssociatedCallback& associated_callback)
+ : file_path_(file_path),
+ db_error_(false),
+ is_inconsistent_(false),
+ next_namespace_id_(0),
+ next_negative_namespace_id_(-1),
+ associated_callback_(associated_callback) {
}
SessionStorageDatabase::~SessionStorageDatabase() {
@@ -159,7 +171,7 @@ bool SessionStorageDatabase::DeleteArea(int64 namespace_id,
return true;
}
leveldb::WriteBatch batch;
- if (!DeleteArea(namespace_id, origin.spec(), &batch))
+ if (!DeleteAreaHelper(namespace_id, origin.spec(), &batch))
return false;
leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
return DatabaseErrorCheck(s.ok());
@@ -178,14 +190,68 @@ bool SessionStorageDatabase::DeleteNamespace(int64 namespace_id) {
for (std::map<std::string, std::string>::const_iterator it = areas.begin();
it != areas.end(); ++it) {
const std::string& origin = it->first;
- if (!DeleteArea(namespace_id, origin, &batch))
+ if (!DeleteAreaHelper(namespace_id, origin, &batch))
return false;
}
- batch.Delete(NamespaceStartKey(namespace_id, namespace_offset_));
+ batch.Delete(NamespaceStartKey(namespace_id));
leveldb::Status s = db_->Write(leveldb::WriteOptions(), &batch);
return DatabaseErrorCheck(s.ok());
}
+bool SessionStorageDatabase::ReadNamespaceIds(
+ std::vector<int64>* namespace_ids) {
+ if (!LazyOpen(true))
+ return false;
+
+ std::string namespace_prefix = NamespacePrefix();
+ scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
+ it->Seek(namespace_prefix);
+ if (it->status().IsNotFound())
+ return true;
+
+ if (!DatabaseErrorCheck(it->status().ok()))
+ return false;
+
+ // Skip the dummy entry "namespace-" and iterate the namespaces.
+ for (it->Next(); it->Valid(); it->Next()) {
+ std::string key = it->key().ToString();
+ if (key.find(namespace_prefix) != 0) {
+ // Iterated past the "namespace-" keys.
+ break;
+ }
+ size_t second_dash = key.find('-', namespace_prefix.length());
+ if (second_dash != std::string::npos)
+ continue;
+
+ // The key is of the form "namespace-<namespaceid>".
+ std::string namespace_id_str = key.substr(namespace_prefix.length());
+ int64 real_namespace_id;
+ bool conversion_ok =
+ base::StringToInt64(namespace_id_str, &real_namespace_id);
+ if (!ConsistencyCheck(conversion_ok))
+ return false;
+ std::map<int64, int64>::const_iterator it =
+ real_id_to_id_.find(real_namespace_id);
+ if (it != real_id_to_id_.end()) {
+ namespace_ids->push_back(it->second);
+ } else {
+ // There is no known upper layer ID for this namespace. Create one. (The
+ // upper layer will only create positive IDs, so this won't overlap with
+ // the IDs created by it.)
+ int64 upper_layer_id = next_negative_namespace_id_--;
+ AssociateNamespaceId(upper_layer_id, real_namespace_id);
+ namespace_ids->push_back(upper_layer_id);
+ }
+ }
+ return true;
+}
+
+void SessionStorageDatabase::AssociateNamespaceId(int64 namespace_id,
+ int64 real_id) {
+ id_to_real_id_[namespace_id] = real_id;
+ real_id_to_id_[real_id] = namespace_id;
+}
+
bool SessionStorageDatabase::LazyOpen(bool create_if_needed) {
base::AutoLock auto_lock(db_lock_);
if (db_error_ || is_inconsistent_) {
@@ -224,8 +290,7 @@ bool SessionStorageDatabase::LazyOpen(bool create_if_needed) {
}
}
db_.reset(db);
-
- return GetNextNamespaceId(&namespace_offset_);
+ return GetNextNamespaceId(&next_namespace_id_);
}
leveldb::Status SessionStorageDatabase::TryToOpen(leveldb::DB** db) {
@@ -284,8 +349,7 @@ bool SessionStorageDatabase::CreateNamespace(int64 namespace_id,
if (s.IsNotFound())
batch->Put(namespace_prefix, "");
- std::string namespace_start_key =
- NamespaceStartKey(namespace_id, namespace_offset_);
+ std::string namespace_start_key = NamespaceStartKey(namespace_id);
s = db_->Get(leveldb::ReadOptions(), namespace_start_key, &dummy);
if (!DatabaseErrorCheck(s.ok() || s.IsNotFound()))
return false;
@@ -316,8 +380,11 @@ bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id,
int64 next_namespace_id;
if (!GetNextNamespaceId(&next_namespace_id))
return false;
- if (next_namespace_id < namespace_id + namespace_offset_ + 1) {
- next_namespace_id = namespace_id + namespace_offset_ + 1;
+ int64 real_id;
+ if (!GetRealId(namespace_id, &real_id))
+ return false;
+ if (next_namespace_id < real_id + 1) {
+ next_namespace_id = real_id + 1;
batch->Put(NextNamespaceIdKey(), base::Int64ToString(next_namespace_id));
}
return true;
@@ -326,8 +393,7 @@ bool SessionStorageDatabase::UpdateNextNamespaceId(int64 namespace_id,
bool SessionStorageDatabase::GetAreasInNamespace(
int64 namespace_id,
std::map<std::string, std::string>* areas) {
- return GetAreasInNamespace(NamespaceIdStr(namespace_id, namespace_offset_),
- areas);
+ return GetAreasInNamespace(NamespaceIdStr(namespace_id), areas);
}
bool SessionStorageDatabase::GetAreasInNamespace(
@@ -352,8 +418,8 @@ bool SessionStorageDatabase::GetAreasInNamespace(
break;
}
size_t second_dash = key.find('-', namespace_start_key.length());
- if (!ConsistencyCheck(second_dash != std::string::npos))
- return false;
+ if (second_dash == std::string::npos)
+ break;
std::string origin = key.substr(second_dash + 1);
std::string map_id = it->value().ToString();
(*areas)[origin] = map_id;
@@ -365,21 +431,21 @@ void SessionStorageDatabase::AddAreaToNamespace(int64 namespace_id,
const std::string& origin,
const std::string& map_id,
leveldb::WriteBatch* batch) {
- std::string namespace_key = NamespaceKey(
- NamespaceIdStr(namespace_id, namespace_offset_), origin);
+ std::string namespace_key =
+ NamespaceKey(NamespaceIdStr(namespace_id), origin);
batch->Put(namespace_key, map_id);
}
-bool SessionStorageDatabase::DeleteArea(int64 namespace_id,
- const std::string& origin,
- leveldb::WriteBatch* batch) {
- return DeleteArea(NamespaceIdStr(namespace_id, namespace_offset_),
- origin, batch);
+bool SessionStorageDatabase::DeleteAreaHelper(int64 namespace_id,
+ const std::string& origin,
+ leveldb::WriteBatch* batch) {
+ return DeleteAreaHelper(NamespaceIdStr(namespace_id), origin, batch);
}
-bool SessionStorageDatabase::DeleteArea(const std::string& namespace_id_str,
- const std::string& origin,
- leveldb::WriteBatch* batch) {
+bool SessionStorageDatabase::DeleteAreaHelper(
+ const std::string& namespace_id_str,
+ const std::string& origin,
+ leveldb::WriteBatch* batch) {
std::string map_id;
bool exists;
if (!GetMapForArea(namespace_id_str, origin, &exists, &map_id))
@@ -397,9 +463,11 @@ bool SessionStorageDatabase::GetMapForArea(int64 namespace_id,
const GURL& origin,
bool* exists,
std::string* map_id) {
- return GetMapForArea(
- base::Int64ToString(namespace_id + namespace_offset_),
- origin.spec(), exists, map_id);
+ int64 real_id;
+ if (!GetRealId(namespace_id, &real_id))
+ return false;
+ return GetMapForArea(base::Int64ToString(real_id), origin.spec(),
+ exists, map_id);
}
bool SessionStorageDatabase::GetMapForArea(const std::string& namespace_id_str,
@@ -432,8 +500,7 @@ bool SessionStorageDatabase::CreateMapForArea(int64 namespace_id,
return false;
}
batch->Put(next_map_id_key, base::Int64ToString(++next_map_id));
- std::string namespace_key =
- NamespaceKey(namespace_id, namespace_offset_, origin);
+ std::string namespace_key = NamespaceKey(namespace_id, origin);
batch->Put(namespace_key, *map_id);
batch->Put(MapRefCountKey(*map_id), "1");
return true;
@@ -584,14 +651,36 @@ bool SessionStorageDatabase::DeepCopyArea(
return true;
}
+bool SessionStorageDatabase::AllocateNamespaceId(int64* namespace_id) {
+ if (!LazyOpen(true))
+ return false;
+ *namespace_id = next_namespace_id_++;
+ // The next namespace id field in the db will be increased when data is
+ // actually written to the namespace.
+ return true;
+}
+
+bool SessionStorageDatabase::GetRealId(int64 namespace_id, int64* real_id) {
+ std::map<int64, int64>::const_iterator it = id_to_real_id_.find(namespace_id);
+ if (it != id_to_real_id_.end()) {
+ *real_id = it->second;
+ return true;
+ }
+ if (!AllocateNamespaceId(real_id))
+ return false;
+ if (!associated_callback_.is_null())
+ associated_callback_.Run(namespace_id, *real_id);
+ AssociateNamespaceId(namespace_id, *real_id);
+ return true;
+}
+
std::string SessionStorageDatabase::NamespaceStartKey(
const std::string& namespace_id_str) {
return base::StringPrintf("namespace-%s", namespace_id_str.c_str());
}
-std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id,
- int64 namespace_offset) {
- return NamespaceStartKey(NamespaceIdStr(namespace_id, namespace_offset));
+std::string SessionStorageDatabase::NamespaceStartKey(int64 namespace_id) {
+ return NamespaceStartKey(NamespaceIdStr(namespace_id));
}
std::string SessionStorageDatabase::NamespaceKey(
@@ -600,15 +689,16 @@ std::string SessionStorageDatabase::NamespaceKey(
origin.c_str());
}
-std::string SessionStorageDatabase::NamespaceKey(
- int64 namespace_id, int64 namespace_offset, const GURL& origin) {
- return NamespaceKey(NamespaceIdStr(namespace_id, namespace_offset),
- origin.spec());
+std::string SessionStorageDatabase::NamespaceKey(int64 namespace_id,
+ const GURL& origin) {
+ return NamespaceKey(NamespaceIdStr(namespace_id), origin.spec());
}
-std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id,
- int64 namespace_offset) {
- return base::Int64ToString(namespace_id + namespace_offset);
+std::string SessionStorageDatabase::NamespaceIdStr(int64 namespace_id) {
+ int64 real_id;
+ if (!GetRealId(namespace_id, &real_id))
+ return "";
+ return base::Int64ToString(real_id);
}
const char* SessionStorageDatabase::NamespacePrefix() {

Powered by Google App Engine
This is Rietveld 408576698