Commit 9636306b authored by marja@chromium.org's avatar marja@chromium.org

SessionStorageDatabase fix: Delete namespace keys if there are no areas.

Before the change, the database would contain leftover "namespace-namespaceid-"
keys with no areas. This change ensures that they are not left over, and that
the existing leftover keys are scavenged. (This will delete the leftover data
for users who have it.)

BUG=175232
R=michaeln


Review URL: https://chromiumcodereview.appspot.com/12224092

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@182259 0039d316-1c4b-4281-b951-d872f2087c98
parent 41168e2a
...@@ -240,6 +240,10 @@ bool SessionStorageDatabase::ReadNamespacesAndOrigins( ...@@ -240,6 +240,10 @@ bool SessionStorageDatabase::ReadNamespacesAndOrigins(
current_namespace_id = current_namespace_id =
key.substr(namespace_prefix.length(), key.substr(namespace_prefix.length(),
key.length() - namespace_prefix.length() - 1); key.length() - namespace_prefix.length() - 1);
// Ensure that we keep track of the namespace even if it doesn't contain
// any origins.
namespaces_and_origins->insert(
std::make_pair(current_namespace_id, std::vector<GURL>()));
} else { } else {
// The key is of the form "namespace-<namespaceid>-<origin>". // The key is of the form "namespace-<namespaceid>-<origin>".
std::string origin = key.substr(current_namespace_start_key.length()); std::string origin = key.substr(current_namespace_start_key.length());
...@@ -411,6 +415,25 @@ bool SessionStorageDatabase::DeleteAreaHelper( ...@@ -411,6 +415,25 @@ bool SessionStorageDatabase::DeleteAreaHelper(
return false; return false;
std::string namespace_key = NamespaceKey(namespace_id, origin); std::string namespace_key = NamespaceKey(namespace_id, origin);
batch->Delete(namespace_key); batch->Delete(namespace_key);
// If this was the only area in the namespace, delete the namespace start key,
// too.
std::string namespace_start_key = NamespaceStartKey(namespace_id);
scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
it->Seek(namespace_start_key);
if (!ConsistencyCheck(it->Valid()))
return false;
// Advance the iterator 2 times (we still haven't really deleted
// namespace_key).
it->Next();
if (!ConsistencyCheck(it->Valid()))
return false;
it->Next();
if (!it->Valid())
return true;
std::string key = it->key().ToString();
if (key.find(namespace_start_key) != 0)
batch->Delete(namespace_start_key);
return true; return true;
} }
......
...@@ -83,7 +83,7 @@ class SessionStorageDatabaseTest : public testing::Test { ...@@ -83,7 +83,7 @@ class SessionStorageDatabaseTest : public testing::Test {
SessionStorageDatabaseTest::SessionStorageDatabaseTest() SessionStorageDatabaseTest::SessionStorageDatabaseTest()
: kOrigin1("http://www.origin1.com"), : kOrigin1("http://www.origin1.com"),
kOrigin2("http://www.origin2.com"), kOrigin2("http://www.origin2.com"),
kNamespace1("1"), kNamespace1("namespace1"),
kNamespace2("namespace2"), kNamespace2("namespace2"),
kNamespaceClone("wascloned"), kNamespaceClone("wascloned"),
kKey1(ASCIIToUTF16("key1")), kKey1(ASCIIToUTF16("key1")),
...@@ -213,6 +213,7 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const { ...@@ -213,6 +213,7 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
// Iterate the "namespace-" keys. // Iterate the "namespace-" keys.
std::set<std::string> found_namespace_ids; std::set<std::string> found_namespace_ids;
std::set<std::string> namespaces_with_areas;
std::map<int64, int64> expected_map_refcounts; std::map<int64, int64> expected_map_refcounts;
int64 max_map_id = -1; int64 max_map_id = -1;
...@@ -228,6 +229,7 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const { ...@@ -228,6 +229,7 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
// has been read by now, since the keys are stored in order. // has been read by now, since the keys are stored in order.
ASSERT_TRUE(found_namespace_ids.find(namespace_id) != ASSERT_TRUE(found_namespace_ids.find(namespace_id) !=
found_namespace_ids.end()); found_namespace_ids.end());
namespaces_with_areas.insert(namespace_id);
int64 map_id; int64 map_id;
bool conversion_ok = base::StringToInt64(it->second, &map_id); bool conversion_ok = base::StringToInt64(it->second, &map_id);
ASSERT_TRUE(conversion_ok); ASSERT_TRUE(conversion_ok);
...@@ -237,6 +239,10 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const { ...@@ -237,6 +239,10 @@ void SessionStorageDatabaseTest::CheckDatabaseConsistency() const {
++valid_keys; ++valid_keys;
} }
} }
// Check that there are no leftover "namespace-namespaceid-" keys without
// associated areas.
ASSERT_EQ(found_namespace_ids.size(), namespaces_with_areas.size());
if (max_map_id != -1) { if (max_map_id != -1) {
// The database contains maps. // The database contains maps.
ASSERT_TRUE(data.find(next_map_id_key) != data.end()); ASSERT_TRUE(data.find(next_map_id_key) != data.end());
...@@ -773,4 +779,20 @@ TEST_F(SessionStorageDatabaseTest, ReadOriginsInNamespace) { ...@@ -773,4 +779,20 @@ TEST_F(SessionStorageDatabaseTest, ReadOriginsInNamespace) {
CheckDatabaseConsistency(); CheckDatabaseConsistency();
} }
TEST_F(SessionStorageDatabaseTest, DeleteAllOrigins) {
// Write data for a namespace, for 2 origins.
ValuesMap data1;
data1[kKey1] = kValue1;
ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data1));
ValuesMap data2;
data2[kKey1] = kValue2;
ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin2, false, data2));
EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin1));
EXPECT_TRUE(db_->DeleteArea(kNamespace1, kOrigin2));
// Check that also the namespace start key was deleted.
CheckDatabaseConsistency();
}
} // namespace dom_storage } // namespace dom_storage
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment