Chromium Code Reviews| Index: chrome/browser/value_store/leveldb_value_store.cc |
| diff --git a/chrome/browser/value_store/leveldb_value_store.cc b/chrome/browser/value_store/leveldb_value_store.cc |
| index 043bcb3d1915f4e3a316f871d9ff06f47aa8f1cb..d6712eaa3bbe90f3ce1879cc38b8e91cf4f2dce7 100644 |
| --- a/chrome/browser/value_store/leveldb_value_store.cc |
| +++ b/chrome/browser/value_store/leveldb_value_store.cc |
| @@ -269,6 +269,56 @@ ValueStore::WriteResult LeveldbValueStore::Clear() { |
| return MakeWriteResult(changes.Pass()); |
| } |
| +bool LeveldbValueStore::Restore() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + |
| + ReadResult result = Get(); |
| + std::string previous_key; |
| + while (result->HasError() && result->error().code == CORRUPTION) { |
| + // If we don't have a specific corrupted key, or we've tried and failed to |
| + // clear this specific key, or we fail to restore the key, then wipe the |
| + // whole database. |
| + if (!result->error().key.get() || *result->error().key == previous_key || |
| + !RestoreKey(*result->error().key)) { |
| + DeleteDbFile(); |
| + result = Get(); |
| + break; |
| + } |
| + |
| + // Otherwise, re-Get() the database to check if there is still any |
| + // corruption. |
| + previous_key = *result->error().key; |
| + result = Get(); |
| + } |
| + |
| + // If we still have an error, it means we've tried deleting the database file, |
| + // and failed. There's nothing more we can do. |
| + return !(result->HasError() && result->error().code == CORRUPTION); |
| +} |
| + |
| +bool LeveldbValueStore::RestoreKey(const std::string& key) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + |
| + ReadResult result = Get(key); |
| + if (result->HasError() && result->error().code == CORRUPTION) { |
|
not at google - send to devlin
2014/02/14 19:35:56
all my talk of making corruption a switch... turns
Devlin
2014/02/18 23:55:22
Done.
|
| + leveldb::WriteBatch batch; |
| + batch.Delete(key); |
| + scoped_ptr<ValueStore::Error> error = WriteToDb(&batch); |
| + // If we can't delete the key, the restore failed. |
| + if (error.get()) |
| + return false; |
| + result = Get(key); |
| + } |
| + |
| + // The restore succeeded if there is no corruption error. |
| + return !(result->HasError() && result->error().code == CORRUPTION); |
|
not at google - send to devlin
2014/02/14 19:35:56
return !result->HasError() || result->error().code
Devlin
2014/02/18 23:55:22
Done.
|
| +} |
| + |
| +bool LeveldbValueStore::WriteToDbForTest(leveldb::WriteBatch* batch) { |
| + scoped_ptr<ValueStore::Error> error = WriteToDb(batch); |
|
not at google - send to devlin
2014/02/14 19:35:56
inline this
Devlin
2014/02/18 23:55:22
Done.
|
| + return !error.get(); |
| +} |
| + |
| scoped_ptr<ValueStore::Error> LeveldbValueStore::EnsureDbIsOpen() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |