blob: 8720b3024c636c3795916690cb7ea105e747e0b2 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_LEVELDB_PROTO_UNIQUE_PROTO_DATABASE_H_
#define COMPONENTS_LEVELDB_PROTO_UNIQUE_PROTO_DATABASE_H_
#include "base/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "components/leveldb_proto/leveldb_database.h"
#include "components/leveldb_proto/proto_database.h"
#include "components/leveldb_proto/proto_leveldb_wrapper.h"
namespace leveldb_proto {
// An implementation of ProtoDatabase<T> that manages the lifecycle of a unique
// LevelDB instance.
template <typename T>
class UniqueProtoDatabase : public ProtoDatabase<T> {
public:
explicit UniqueProtoDatabase(
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
explicit UniqueProtoDatabase(std::unique_ptr<ProtoLevelDBWrapper>);
virtual ~UniqueProtoDatabase();
UniqueProtoDatabase(
const base::FilePath& database_dir,
const leveldb_env::Options& options,
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
// This version of Init is for compatibility, since many of the current
// proto database still use this.
void Init(const char* client_name,
const base::FilePath& database_dir,
const leveldb_env::Options& options,
typename Callbacks::InitCallback callback) override;
void Init(const std::string& client_name,
Callbacks::InitStatusCallback callback) override;
void InitWithDatabase(LevelDB* database,
const base::FilePath& database_dir,
const leveldb_env::Options& options,
Callbacks::InitStatusCallback callback) override;
void UpdateEntries(std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
entries_to_save,
std::unique_ptr<std::vector<std::string>> keys_to_remove,
Callbacks::UpdateCallback callback) override;
void UpdateEntriesWithRemoveFilter(
std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
entries_to_save,
const LevelDB::KeyFilter& delete_key_filter,
Callbacks::UpdateCallback callback) override;
void UpdateEntriesWithRemoveFilter(
std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
entries_to_save,
const LevelDB::KeyFilter& delete_key_filter,
const std::string& target_prefix,
Callbacks::UpdateCallback callback) override;
void LoadEntries(
typename Callbacks::Internal<T>::LoadCallback callback) override;
void LoadEntriesWithFilter(
const LevelDB::KeyFilter& filter,
typename Callbacks::Internal<T>::LoadCallback callback) override;
void LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename Callbacks::Internal<T>::LoadCallback callback) override;
void LoadKeysAndEntries(
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
override;
void LoadKeysAndEntriesWithFilter(
const LevelDB::KeyFilter& filter,
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
override;
void LoadKeysAndEntriesWithFilter(
const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
override;
void LoadKeysAndEntriesInRange(
const std::string& start,
const std::string& end,
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
override;
void LoadKeys(Callbacks::LoadKeysCallback callback) override;
void LoadKeys(const std::string& target_prefix,
Callbacks::LoadKeysCallback callback) override;
void GetEntry(const std::string& key,
typename Callbacks::Internal<T>::GetCallback callback) override;
void Destroy(Callbacks::DestroyCallback callback) override;
void RemoveKeysForTesting(const LevelDB::KeyFilter& key_filter,
const std::string& target_prefix,
Callbacks::UpdateCallback callback);
bool GetApproximateMemoryUse(uint64_t* approx_mem_use);
// Sets the identifier used by the underlying LevelDB wrapper to record
// metrics.
void SetMetricsId(const std::string& id);
protected:
std::unique_ptr<ProtoLevelDBWrapper> db_wrapper_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
private:
THREAD_CHECKER(thread_checker_);
base::FilePath database_dir_;
leveldb_env::Options options_;
std::unique_ptr<LevelDB> db_;
};
template <typename T>
UniqueProtoDatabase<T>::UniqueProtoDatabase(
const scoped_refptr<base::SequencedTaskRunner>& task_runner)
: db_wrapper_(std::make_unique<ProtoLevelDBWrapper>(task_runner)) {}
template <typename T>
UniqueProtoDatabase<T>::UniqueProtoDatabase(
std::unique_ptr<ProtoLevelDBWrapper> db_wrapper)
: db_wrapper_(std::move(db_wrapper)) {}
template <typename T>
UniqueProtoDatabase<T>::UniqueProtoDatabase(
const base::FilePath& database_dir,
const leveldb_env::Options& options,
const scoped_refptr<base::SequencedTaskRunner>& task_runner)
: UniqueProtoDatabase<T>(task_runner) {
database_dir_ = database_dir;
options_ = options;
}
template <typename T>
UniqueProtoDatabase<T>::~UniqueProtoDatabase() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (db_.get() &&
!db_wrapper_->task_runner()->DeleteSoon(FROM_HERE, db_.release())) {
DLOG(WARNING) << "Proto database will not be deleted.";
}
}
template <typename T>
void UniqueProtoDatabase<T>::Init(const std::string& client_name,
Callbacks::InitStatusCallback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
db_ = std::make_unique<LevelDB>(client_name.c_str());
db_wrapper_->SetMetricsId(client_name);
InitWithDatabase(db_.get(), database_dir_, options_, std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::Init(const char* client_name,
const base::FilePath& database_dir,
const leveldb_env::Options& options,
Callbacks::InitCallback callback) {
database_dir_ = database_dir;
options_ = options;
db_wrapper_->SetMetricsId(client_name);
Init(std::string(client_name),
base::BindOnce(
[](Callbacks::InitCallback callback, Enums::InitStatus status) {
std::move(callback).Run(status == Enums::InitStatus::kOK);
},
std::move(callback)));
}
template <typename T>
void UniqueProtoDatabase<T>::InitWithDatabase(
LevelDB* database,
const base::FilePath& database_dir,
const leveldb_env::Options& options,
Callbacks::InitStatusCallback callback) {
// We set |destroy_on_corruption| to true to preserve the original behaviour
// where database corruption led to automatic destruction.
db_wrapper_->InitWithDatabase(database, database_dir, options,
true /* destroy_on_corruption */,
std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::UpdateEntries(
std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
std::unique_ptr<std::vector<std::string>> keys_to_remove,
Callbacks::UpdateCallback callback) {
db_wrapper_->template UpdateEntries<T>(std::move(entries_to_save),
std::move(keys_to_remove),
std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::UpdateEntriesWithRemoveFilter(
std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
const LevelDB::KeyFilter& delete_key_filter,
Callbacks::UpdateCallback callback) {
db_wrapper_->template UpdateEntriesWithRemoveFilter<T>(
std::move(entries_to_save), delete_key_filter, std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::UpdateEntriesWithRemoveFilter(
std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
const LevelDB::KeyFilter& delete_key_filter,
const std::string& target_prefix,
Callbacks::UpdateCallback callback) {
db_wrapper_->template UpdateEntriesWithRemoveFilter<T>(
std::move(entries_to_save), delete_key_filter, target_prefix,
std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadEntries(
typename Callbacks::Internal<T>::LoadCallback callback) {
db_wrapper_->template LoadEntries<T>(std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& filter,
typename Callbacks::Internal<T>::LoadCallback callback) {
db_wrapper_->template LoadEntriesWithFilter<T>(filter, std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadEntriesWithFilter(
const LevelDB::KeyFilter& key_filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename Callbacks::Internal<T>::LoadCallback callback) {
db_wrapper_->template LoadEntriesWithFilter<T>(
key_filter, options, target_prefix, std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadKeysAndEntries(
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
db_wrapper_->template LoadKeysAndEntries<T>(std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadKeysAndEntriesWithFilter(
const LevelDB::KeyFilter& filter,
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(filter,
std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadKeysAndEntriesWithFilter(
const LevelDB::KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(
filter, options, target_prefix, std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadKeysAndEntriesInRange(
const std::string& start,
const std::string& end,
typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
db_wrapper_->template LoadKeysAndEntriesInRange<T>(start, end,
std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadKeys(Callbacks::LoadKeysCallback callback) {
db_wrapper_->LoadKeys(std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::LoadKeys(const std::string& target_prefix,
Callbacks::LoadKeysCallback callback) {
db_wrapper_->LoadKeys(target_prefix, std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::GetEntry(
const std::string& key,
typename Callbacks::Internal<T>::GetCallback callback) {
db_wrapper_->template GetEntry<T>(key, std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::Destroy(Callbacks::DestroyCallback callback) {
db_wrapper_->Destroy(std::move(callback));
}
template <typename T>
void UniqueProtoDatabase<T>::RemoveKeysForTesting(
const LevelDB::KeyFilter& key_filter,
const std::string& target_prefix,
Callbacks::UpdateCallback callback) {
db_wrapper_->RemoveKeys(key_filter, target_prefix, std::move(callback));
}
template <typename T>
bool UniqueProtoDatabase<T>::GetApproximateMemoryUse(uint64_t* approx_mem_use) {
return db_wrapper_->GetApproximateMemoryUse(approx_mem_use);
}
template <typename T>
void UniqueProtoDatabase<T>::SetMetricsId(const std::string& id) {
db_wrapper_->SetMetricsId(id);
}
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_UNIQUE_PROTO_DATABASE_H_