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) {
bool LevelDB::LoadWithFilter(const KeyFilter& filter,
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_);
if (!db_)
return false;
leveldb::ReadOptions 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()) {
leveldb::Slice key_slice = db_iterator->key();
if (!filter.Run(std::string(key_slice.data(), key_slice.size())))
......
......@@ -58,6 +58,10 @@ class LevelDB {
virtual bool Load(std::vector<std::string>* entries);
virtual bool LoadWithFilter(const KeyFilter& filter,
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 Get(const std::string& key, bool* found, std::string* entry);
// Close (if currently open) and then destroy (i.e. delete) the database
......
......@@ -74,6 +74,10 @@ class ProtoDatabase {
// ProtoDatabase's taskrunner.
virtual void LoadEntriesWithFilter(const LevelDB::KeyFilter& filter,
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
// those keys when complete.
......
......@@ -57,7 +57,12 @@ class ProtoDatabaseImpl : public ProtoDatabase<T> {
typename ProtoDatabase<T>::UpdateCallback callback) override;
void LoadEntries(typename ProtoDatabase<T>::LoadCallback callback) override;
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;
void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override;
void GetEntry(const std::string& key,
......@@ -181,6 +186,8 @@ void UpdateEntriesWithRemoveFilterFromTaskRunner(
template <typename T>
void LoadEntriesFromTaskRunner(LevelDB* database,
const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
std::vector<T>* entries,
bool* success) {
DCHECK(success);
......@@ -189,7 +196,8 @@ void LoadEntriesFromTaskRunner(LevelDB* database,
entries->clear();
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) {
T entry;
......@@ -339,6 +347,16 @@ template <typename T>
void ProtoDatabaseImpl<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter,
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());
bool* success = new bool(false);
......@@ -349,7 +367,7 @@ void ProtoDatabaseImpl<T>::LoadEntriesWithFilter(
task_runner_->PostTaskAndReply(
FROM_HERE,
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::Owned(success), std::move(entries)));
}
......
......@@ -57,6 +57,11 @@ class MockDB : public LevelDB {
MOCK_METHOD1(Load, bool(std::vector<std::string>*));
MOCK_METHOD2(LoadWithFilter,
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_METHOD0(Destroy, bool());
......@@ -282,7 +287,7 @@ TEST_F(ProtoDatabaseImplTest, TestDBLoadSuccess) {
base::BindOnce(&MockDatabaseCaller::InitCallback,
base::Unretained(&caller)));
EXPECT_CALL(*mock_db, LoadWithFilter(_, _))
EXPECT_CALL(*mock_db, LoadWithFilter(_, _, _, _))
.WillOnce(AppendLoadEntries(model));
EXPECT_CALL(caller, LoadCallback1(true, _))
.WillOnce(VerifyLoadEntries(testing::ByRef(model)));
......@@ -304,7 +309,7 @@ TEST_F(ProtoDatabaseImplTest, TestDBLoadFailure) {
base::BindOnce(&MockDatabaseCaller::InitCallback,
base::Unretained(&caller)));
EXPECT_CALL(*mock_db, LoadWithFilter(_, _)).WillOnce(Return(false));
EXPECT_CALL(*mock_db, LoadWithFilter(_, _, _, _)).WillOnce(Return(false));
EXPECT_CALL(caller, LoadCallback1(false, _));
db_->LoadEntries(base::BindOnce(&MockDatabaseCaller::LoadCallback,
base::Unretained(&caller)));
......
......@@ -48,6 +48,11 @@ class FakeDB : public ProtoDatabase<T> {
void LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_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;
void LoadKeys(typename ProtoDatabase<T>::LoadKeysCallback callback) override;
void GetEntry(const std::string& key,
typename ProtoDatabase<T>::GetCallback callback) override;
......@@ -152,11 +157,23 @@ template <typename T>
void FakeDB<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter,
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>());
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);
}
}
load_callback_ =
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