1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_SELECTOR_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_SELECTOR_H_
#include <memory>
#include <string>
#include "base/component_export.h"
#include "base/containers/queue.h"
#include "base/files/file_path.h"
#include "base/task/sequenced_task_runner.h"
#include "components/leveldb_proto/internal/proto_leveldb_wrapper.h"
#include "components/leveldb_proto/public/shared_proto_database_client_list.h"
namespace leveldb_proto {
class MigrationDelegate;
class SharedProtoDatabase;
class SharedProtoDatabaseClient;
class SharedProtoDatabaseProvider;
class UniqueProtoDatabase;
// A wrapper around unique and shared database client. Handles initialization of
// underlying database as unique or shared as requested.
// TODO: Discuss the init flow/migration path for unique/shared DB here.
class COMPONENT_EXPORT(LEVELDB_PROTO) ProtoDatabaseSelector
: public base::RefCountedThreadSafe<ProtoDatabaseSelector> {
public:
// These values are logged to UMA. Entries should not be renumbered and
// numeric values should never be reused. Please keep in sync with
// "ProtoDatabaseInitState" in src/tools/metrics/histograms/enums.xml.
enum class ProtoDatabaseInitState {
kSharedDbInitAttempted = 0,
kFailureUniqueDbCorrupted = 1,
kFailureNoDatabaseProvider = 2, // Deprecated.
kBothUniqueAndSharedFailedOpen = 3,
kSharedDbClientMissingInitFailed = 4,
kSharedDbClientMissingUniqueReturned = 5,
kSharedDbOpenFailed = 6,
kUniqueDbMissingSharedReturned = 7,
kUniqueDbOpenFailed = 8,
kMigrateToSharedAttempted = 9,
kMigrateToUniqueAttempted = 10,
kMigratedSharedDbOpened = 11,
kDeletionOfOldDataFailed = 12,
kMigrateToSharedFailed = 13,
kMigrateToUniqueFailed = 14,
kMigrateToSharedCompleteDeletionFailed = 15,
kMigrateToUniqueCompleteDeletionFailed = 16,
kMigrateToSharedSuccess = 17,
kMigrateToUniqueSuccess = 18,
kLegacyInitCalled = 19,
kSharedDbMetadataLoadFailed = 20,
kSharedDbMetadataWriteFailed = 21,
kSharedDbClientCorrupt = 22,
kSharedDbClientSuccess = 23,
kSharedLevelDbInitFailure = 24,
kSharedDbClientMissing = 25,
kFailureNoSharedDBProviderUniqueFailed = 26,
kSuccessNoSharedDBProviderUniqueSucceeded = 27,
kFailureUniqueDbMissingClearSharedFailed = 28,
kDeletedSharedDbOnRepeatedFailures = 29,
kDeletionOfSharedDbFailed = 30,
kMaxValue = kDeletionOfSharedDbFailed,
};
static void RecordInitState(ProtoDatabaseInitState state);
ProtoDatabaseSelector(
ProtoDbType db_type,
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::unique_ptr<SharedProtoDatabaseProvider> db_provider);
void InitWithDatabase(
LevelDB* database,
const base::FilePath& database_dir,
const leveldb_env::Options& options,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
Callbacks::InitStatusCallback callback);
void InitUniqueOrShared(
const std::string& client_name,
base::FilePath db_dir,
const leveldb_env::Options& unique_db_options,
bool use_shared_db,
scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
Callbacks::InitStatusCallback callback);
void AddTransaction(base::OnceClosure task);
// DO NOT USE any of the functions below directly. They should be posted as
// transaction tasks using AddTransaction().
void UpdateEntries(std::unique_ptr<KeyValueVector> entries_to_save,
std::unique_ptr<KeyVector> keys_to_remove,
Callbacks::UpdateCallback callback);
void UpdateEntriesWithRemoveFilter(
std::unique_ptr<KeyValueVector> entries_to_save,
const KeyFilter& delete_key_filter,
Callbacks::UpdateCallback callback);
void LoadEntries(typename Callbacks::LoadCallback callback);
void LoadEntriesWithFilter(const KeyFilter& key_filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename Callbacks::LoadCallback callback);
void LoadKeysAndEntries(
typename Callbacks::LoadKeysAndEntriesCallback callback);
void LoadKeysAndEntriesWithFilter(
const KeyFilter& filter,
const leveldb::ReadOptions& options,
const std::string& target_prefix,
typename Callbacks::LoadKeysAndEntriesCallback callback);
void LoadKeysAndEntriesInRange(
const std::string& start,
const std::string& end,
typename Callbacks::LoadKeysAndEntriesCallback callback);
void LoadKeysAndEntriesWhile(
const std::string& start,
const KeyIteratorController& controller,
typename Callbacks::LoadKeysAndEntriesCallback callback);
void LoadKeys(Callbacks::LoadKeysCallback callback);
void GetEntry(const std::string& key,
typename Callbacks::GetCallback callback);
void Destroy(Callbacks::DestroyCallback callback);
void RemoveKeysForTesting(const KeyFilter& key_filter,
const std::string& target_prefix,
Callbacks::UpdateCallback callback);
UniqueProtoDatabase* db_for_testing() { return db_.get(); }
private:
friend class base::RefCountedThreadSafe<ProtoDatabaseSelector>;
template <typename T>
friend class ProtoDatabaseImplTest;
enum class InitStatus {
NOT_STARTED,
IN_PROGRESS,
DONE // success or failure.
};
~ProtoDatabaseSelector();
void OnInitUniqueDB(std::unique_ptr<UniqueProtoDatabase> db,
bool use_shared_db,
Callbacks::InitStatusCallback callback,
Enums::InitStatus status);
void OnInitSharedDB(std::unique_ptr<UniqueProtoDatabase> unique_db,
Enums::InitStatus unique_db_status,
bool use_shared_db,
Callbacks::InitStatusCallback callback,
scoped_refptr<SharedProtoDatabase> shared_db);
void OnGetSharedDBClient(std::unique_ptr<UniqueProtoDatabase> unique_db,
Enums::InitStatus unique_db_status,
bool use_shared_db,
Callbacks::InitStatusCallback callback,
std::unique_ptr<SharedProtoDatabaseClient> client,
Enums::InitStatus shared_db_status);
void DeleteOldDataAndMigrate(
std::unique_ptr<UniqueProtoDatabase> unique_db,
std::unique_ptr<SharedProtoDatabaseClient> client,
bool use_shared_db,
Callbacks::InitStatusCallback callback);
void MaybeDoMigrationOnDeletingOld(
std::unique_ptr<UniqueProtoDatabase> unique_db,
std::unique_ptr<SharedProtoDatabaseClient> client,
Callbacks::InitStatusCallback init_callback,
bool use_shared_db,
bool delete_success);
void OnMigrationTransferComplete(
std::unique_ptr<UniqueProtoDatabase> unique_db,
std::unique_ptr<SharedProtoDatabaseClient> client,
bool use_shared_db,
Callbacks::InitStatusCallback callback,
bool success);
void OnMigrationCleanupComplete(
std::unique_ptr<UniqueProtoDatabase> unique_db,
std::unique_ptr<SharedProtoDatabaseClient> client,
bool use_shared_db,
Callbacks::InitStatusCallback callback,
bool success);
void OnInitDone(ProtoDatabaseInitState state);
void InvokeInitUniqueDbMissingSharedCleared(
std::unique_ptr<SharedProtoDatabaseClient> client,
Callbacks::InitStatusCallback,
bool shared_cleared);
ProtoDbType db_type_;
const scoped_refptr<base::SequencedTaskRunner> task_runner_;
const std::unique_ptr<SharedProtoDatabaseProvider> db_provider_;
const std::unique_ptr<MigrationDelegate> migration_delegate_;
InitStatus init_status_ = InitStatus::NOT_STARTED;
base::queue<base::OnceClosure> pending_tasks_;
std::unique_ptr<UniqueProtoDatabase> db_;
base::FilePath unique_database_dir_;
std::string client_name_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace leveldb_proto
#endif // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_SELECTOR_H_
|