Commit 952e31b2 authored by Troy Hildebrandt's avatar Troy Hildebrandt Committed by Commit Bot

Add additional filtering options to LevelDB/ProtoDatabase LoadEntries.

In preparation for a single shared database for browser features,
additional parameters have been added to LoadWithFilter to allow
only specific entries to be loaded instead of the entire database.
Some minor modifications to FakeDB are made to ensure tests still
build and run.

Bug: 870813
Change-Id: I802331d477ec0ed2d6821c6d937cb2d497560345
Reviewed-on: https://chromium-review.googlesource.com/1169874
Commit-Queue: Troy Hildebrandt <thildebr@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585497}
parent 790625b3
...@@ -168,13 +168,22 @@ bool LevelDB::Load(std::vector<std::string>* entries) { ...@@ -168,13 +168,22 @@ bool LevelDB::Load(std::vector<std::string>* entries) {
bool LevelDB::LoadWithFilter(const KeyFilter& filter, bool LevelDB::LoadWithFilter(const KeyFilter& filter,
std::vector<std::string>* entries) { std::vector<std::string>* entries) {
return LoadWithFilter(filter, entries, leveldb::ReadOptions(), std::string());
}
bool LevelDB::LoadWithFilter(const KeyFilter& filter,
std::vector<std::string>* entries,
const leveldb::ReadOptions& options,
const std::string& target_prefix) {
DFAKE_SCOPED_LOCK(thread_checker_); DFAKE_SCOPED_LOCK(thread_checker_);
if (!db_) if (!db_)
return false; return false;
leveldb::ReadOptions options;
std::unique_ptr<leveldb::Iterator> db_iterator(db_->NewIterator(options)); std::unique_ptr<leveldb::Iterator> db_iterator(db_->NewIterator(options));
for (db_iterator->SeekToFirst(); db_iterator->Valid(); db_iterator->Next()) { leveldb::Slice target(target_prefix);
for (db_iterator->Seek(target);
db_iterator->Valid() && db_iterator->key().starts_with(target);
db_iterator->Next()) {
if (!filter.is_null()) { if (!filter.is_null()) {
leveldb::Slice key_slice = db_iterator->key(); leveldb::Slice key_slice = db_iterator->key();
if (!filter.Run(std::string(key_slice.data(), key_slice.size()))) if (!filter.Run(std::string(key_slice.data(), key_slice.size())))
......
...@@ -58,6 +58,10 @@ class LevelDB { ...@@ -58,6 +58,10 @@ class LevelDB {
virtual bool Load(std::vector<std::string>* entries); virtual bool Load(std::vector<std::string>* entries);
virtual bool LoadWithFilter(const KeyFilter& filter, virtual bool LoadWithFilter(const KeyFilter& filter,
std::vector<std::string>* entries); std::vector<std::string>* entries);
virtual bool LoadWithFilter(const KeyFilter& filter,
std::vector<std::string>* entries,
const leveldb::ReadOptions& options,
const std::string& target_prefix);
virtual bool LoadKeys(std::vector<std::string>* keys); virtual bool LoadKeys(std::vector<std::string>* keys);
virtual bool Get(const std::string& key, bool* found, std::string* entry); virtual bool Get(const std::string& key, bool* found, std::string* entry);
// Close (if currently open) and then destroy (i.e. delete) the database // Close (if currently open) and then destroy (i.e. delete) the database
......
...@@ -74,6 +74,10 @@ class ProtoDatabase { ...@@ -74,6 +74,10 @@ class ProtoDatabase {
// ProtoDatabase's taskrunner. // ProtoDatabase's taskrunner.
virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& filter, virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& filter,
LoadCallback callback) = 0; LoadCallback callback) = 0;
virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
LoadCallback callback) = 0;
// Asynchronously loads all keys from the database and invokes |callback| with // Asynchronously loads all keys from the database and invokes |callback| with
// those keys when complete. // those keys when complete.
......
...@@ -57,7 +57,12 @@ class ProtoDatabaseImpl : public ProtoDatabase<T> { ...@@ -57,7 +57,12 @@ class ProtoDatabaseImpl : public ProtoDatabase<T> {
typename ProtoDatabase<T>::UpdateCallback callback) override; typename ProtoDatabase<T>::UpdateCallback callback) override;
void LoadEntries(typename ProtoDatabase<T>::LoadCallback callback) override; void LoadEntries(typename ProtoDatabase<T>::LoadCallback callback) override;
void LoadEntriesWithFilter( void LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter, const LevelDB::KeyFilter& filter,
typename ProtoDatabase<T>::LoadCallback callback) override;
void LoadEntriesWithFilter(
const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename ProtoDatabase<T>::LoadCallback callback) override; typename ProtoDatabase<T>::LoadCallback callback) override;
void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override; void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override;
void GetEntry(const std::string& key, void GetEntry(const std::string& key,
...@@ -181,6 +186,8 @@ void UpdateEntriesWithRemoveFilterFromTaskRunner( ...@@ -181,6 +186,8 @@ void UpdateEntriesWithRemoveFilterFromTaskRunner(
template <typename T> template <typename T>
void LoadEntriesFromTaskRunner(LevelDB* database, void LoadEntriesFromTaskRunner(LevelDB* database,
const LevelDB::KeyFilter& filter, const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
std::vector<T>* entries, std::vector<T>* entries,
bool* success) { bool* success) {
DCHECK(success); DCHECK(success);
...@@ -189,7 +196,8 @@ void LoadEntriesFromTaskRunner(LevelDB* database, ...@@ -189,7 +196,8 @@ void LoadEntriesFromTaskRunner(LevelDB* database,
entries->clear(); entries->clear();
std::vector<std::string> loaded_entries; std::vector<std::string> loaded_entries;
*success = database->LoadWithFilter(filter, &loaded_entries); *success =
database->LoadWithFilter(filter, &loaded_entries, options, target_prefix);
for (const auto& serialized_entry : loaded_entries) { for (const auto& serialized_entry : loaded_entries) {
T entry; T entry;
...@@ -339,6 +347,16 @@ template <typename T> ...@@ -339,6 +347,16 @@ template <typename T>
void ProtoDatabaseImpl<T>::LoadEntriesWithFilter( void ProtoDatabaseImpl<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter, const LevelDB::KeyFilter& key_filter,
typename ProtoDatabase<T>::LoadCallback callback) { typename ProtoDatabase<T>::LoadCallback callback) {
LoadEntriesWithFilter(key_filter, leveldb::ReadOptions(), std::string(),
std::move(callback));
}
template <typename T>
void ProtoDatabaseImpl<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename ProtoDatabase<T>::LoadCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
bool* success = new bool(false); bool* success = new bool(false);
...@@ -349,7 +367,7 @@ void ProtoDatabaseImpl<T>::LoadEntriesWithFilter( ...@@ -349,7 +367,7 @@ void ProtoDatabaseImpl<T>::LoadEntriesWithFilter(
task_runner_->PostTaskAndReply( task_runner_->PostTaskAndReply(
FROM_HERE, FROM_HERE,
base::BindOnce(LoadEntriesFromTaskRunner<T>, base::Unretained(db_.get()), base::BindOnce(LoadEntriesFromTaskRunner<T>, base::Unretained(db_.get()),
key_filter, entries_ptr, success), key_filter, options, target_prefix, entries_ptr, success),
base::BindOnce(RunLoadCallback<T>, std::move(callback), base::BindOnce(RunLoadCallback<T>, std::move(callback),
base::Owned(success), std::move(entries))); base::Owned(success), std::move(entries)));
} }
......
...@@ -57,6 +57,11 @@ class MockDB : public LevelDB { ...@@ -57,6 +57,11 @@ class MockDB : public LevelDB {
MOCK_METHOD1(Load, bool(std::vector<std::string>*)); MOCK_METHOD1(Load, bool(std::vector<std::string>*));
MOCK_METHOD2(LoadWithFilter, MOCK_METHOD2(LoadWithFilter,
bool(const KeyFilter&, std::vector<std::string>*)); bool(const KeyFilter&, std::vector<std::string>*));
MOCK_METHOD4(LoadWithFilter,
bool(const KeyFilter&,
std::vector<std::string>*,
const leveldb::ReadOptions&,
const std::string&));
MOCK_METHOD3(Get, bool(const std::string&, bool*, std::string*)); MOCK_METHOD3(Get, bool(const std::string&, bool*, std::string*));
MOCK_METHOD0(Destroy, bool()); MOCK_METHOD0(Destroy, bool());
...@@ -282,7 +287,7 @@ TEST_F(ProtoDatabaseImplTest, TestDBLoadSuccess) { ...@@ -282,7 +287,7 @@ TEST_F(ProtoDatabaseImplTest, TestDBLoadSuccess) {
base::BindOnce(&MockDatabaseCaller::InitCallback, base::BindOnce(&MockDatabaseCaller::InitCallback,
base::Unretained(&caller))); base::Unretained(&caller)));
EXPECT_CALL(*mock_db, LoadWithFilter(_, _)) EXPECT_CALL(*mock_db, LoadWithFilter(_, _, _, _))
.WillOnce(AppendLoadEntries(model)); .WillOnce(AppendLoadEntries(model));
EXPECT_CALL(caller, LoadCallback1(true, _)) EXPECT_CALL(caller, LoadCallback1(true, _))
.WillOnce(VerifyLoadEntries(testing::ByRef(model))); .WillOnce(VerifyLoadEntries(testing::ByRef(model)));
...@@ -304,7 +309,7 @@ TEST_F(ProtoDatabaseImplTest, TestDBLoadFailure) { ...@@ -304,7 +309,7 @@ TEST_F(ProtoDatabaseImplTest, TestDBLoadFailure) {
base::BindOnce(&MockDatabaseCaller::InitCallback, base::BindOnce(&MockDatabaseCaller::InitCallback,
base::Unretained(&caller))); base::Unretained(&caller)));
EXPECT_CALL(*mock_db, LoadWithFilter(_, _)).WillOnce(Return(false)); EXPECT_CALL(*mock_db, LoadWithFilter(_, _, _, _)).WillOnce(Return(false));
EXPECT_CALL(caller, LoadCallback1(false, _)); EXPECT_CALL(caller, LoadCallback1(false, _));
db_->LoadEntries(base::BindOnce(&MockDatabaseCaller::LoadCallback, db_->LoadEntries(base::BindOnce(&MockDatabaseCaller::LoadCallback,
base::Unretained(&caller))); base::Unretained(&caller)));
......
...@@ -48,6 +48,11 @@ class FakeDB : public ProtoDatabase<T> { ...@@ -48,6 +48,11 @@ class FakeDB : public ProtoDatabase<T> {
void LoadEntriesWithFilter( void LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter, const LevelDB::KeyFilter& key_filter,
typename ProtoDatabase<T>::LoadCallback callback) override; typename ProtoDatabase<T>::LoadCallback callback) override;
void LoadEntriesWithFilter(
const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename ProtoDatabase<T>::LoadCallback callback) override;
void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override; void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override;
void GetEntry(const std::string& key, void GetEntry(const std::string& key,
typename ProtoDatabase<T>::GetCallback callback) override; typename ProtoDatabase<T>::GetCallback callback) override;
...@@ -152,11 +157,23 @@ template <typename T> ...@@ -152,11 +157,23 @@ template <typename T>
void FakeDB<T>::LoadEntriesWithFilter( void FakeDB<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter, const LevelDB::KeyFilter& key_filter,
typename ProtoDatabase<T>::LoadCallback callback) { typename ProtoDatabase<T>::LoadCallback callback) {
LoadEntriesWithFilter(key_filter, leveldb::ReadOptions(), std::string(),
std::move(callback));
}
template <typename T>
void FakeDB<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename ProtoDatabase<T>::LoadCallback callback) {
std::unique_ptr<std::vector<T>> entries(new std::vector<T>()); std::unique_ptr<std::vector<T>> entries(new std::vector<T>());
for (const auto& pair : *db_) { for (const auto& pair : *db_) {
if (key_filter.is_null() || key_filter.Run(pair.first)) if (key_filter.is_null() || key_filter.Run(pair.first)) {
if (pair.first.compare(0, target_prefix.length(), target_prefix) == 0)
entries->push_back(pair.second); entries->push_back(pair.second);
} }
}
load_callback_ = load_callback_ =
base::BindOnce(RunLoadCallback, std::move(callback), std::move(entries)); base::BindOnce(RunLoadCallback, std::move(callback), std::move(entries));
......
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