File: shared_proto_database_client.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (218 lines) | stat: -rw-r--r-- 8,909 bytes parent folder | download | duplicates (9)
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
217
218
// Copyright 2018 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_SHARED_PROTO_DATABASE_CLIENT_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_CLIENT_H_

#include <memory>
#include <optional>
#include <string>

#include "base/component_export.h"
#include "base/functional/bind.h"
#include "base/sequence_checker.h"
#include "base/types/strong_alias.h"
#include "components/leveldb_proto/internal/leveldb_database.h"
#include "components/leveldb_proto/internal/proto/shared_db_metadata.pb.h"
#include "components/leveldb_proto/internal/unique_proto_database.h"
#include "components/leveldb_proto/public/shared_proto_database_client_list.h"

namespace leveldb_proto {

// Key prefix not visible to the client.
using KeyPrefix = base::StrongAlias<class KeyPrefixTag, std::string>;
// Logical key visible to the client.
using LogicalKey = base::StrongAlias<class LogicalKeyTag, std::string>;
// Physical key used in the underlying db.
using PhysicalKey = base::StrongAlias<class PhysicalKeyTag, std::string>;

class SharedProtoDatabase;

// TODO: Move all these as static or member functions in the class.
using ClientCorruptCallback = base::OnceCallback<void(bool)>;
using SharedClientInitCallback =
    base::OnceCallback<void(Enums::InitStatus,
                            SharedDBMetadataProto::MigrationStatus)>;

// An implementation of ProtoDatabase<T> that uses a shared LevelDB and task
// runner.
// Should be created, destroyed, and used on the same sequenced task runner.
class COMPONENT_EXPORT(LEVELDB_PROTO) SharedProtoDatabaseClient
    : public UniqueProtoDatabase {
 public:
  static KeyPrefix PrefixForDatabase(ProtoDbType db_type);

  static bool HasPrefix(const PhysicalKey& key, const KeyPrefix& prefix);
  static std::optional<LogicalKey> StripPrefix(const PhysicalKey& key,
                                               const KeyPrefix& prefix);

  static std::unique_ptr<KeyVector> PrefixStrings(
      std::unique_ptr<KeyVector> strings,
      const KeyPrefix& prefix);

  static bool KeyFilterStripPrefix(const KeyFilter& key_filter,
                                   const KeyPrefix& prefix,
                                   const PhysicalKey& key);
  static bool KeyStringFilterStripPrefix(const KeyFilter& key_filter,
                                         const KeyPrefix& prefix,
                                         const std::string& key);
  static Enums::KeyIteratorAction KeyIteratorControllerStripPrefix(
      const KeyIteratorController& controller,
      const KeyPrefix& prefix,
      const PhysicalKey& key);
  static Enums::KeyIteratorAction KeyStringIteratorControllerStripPrefix(
      const KeyIteratorController& controller,
      const KeyPrefix& prefix,
      const std::string& key);

  static void GetSharedDatabaseInitStatusAsync(
      const std::string& client_db_id,
      const scoped_refptr<SharedProtoDatabase>& db,
      Callbacks::InitStatusCallback callback);

  static void UpdateClientMetadataAsync(
      const scoped_refptr<SharedProtoDatabase>& db,
      const std::string& client_db_id,
      SharedDBMetadataProto::MigrationStatus migration_status,
      ClientCorruptCallback callback);

  // Destroys all the data from obsolete clients, for the given |db_wrapper|
  // instance. |callback| is called once all the obsolete clients data are
  // removed, with failure status if one or more of the update fails.
  static void DestroyObsoleteSharedProtoDatabaseClients(
      std::unique_ptr<ProtoLevelDBWrapper> db_wrapper,
      Callbacks::UpdateCallback callback);

  // Sets list of client names that are obsolete and will be cleared by next
  // call to DestroyObsoleteSharedProtoDatabaseClients(). |list| is list of dbs
  // with a |LAST| to mark the end of list.
  static void SetObsoleteClientListForTesting(const ProtoDbType* list);

  SharedProtoDatabaseClient(const SharedProtoDatabaseClient&) = delete;
  SharedProtoDatabaseClient& operator=(const SharedProtoDatabaseClient&) =
      delete;

  ~SharedProtoDatabaseClient() override;

  void Init(const std::string& client_uma_name,
            Callbacks::InitStatusCallback callback) override;

  void InitWithDatabase(LevelDB* database,
                        const base::FilePath& database_dir,
                        const leveldb_env::Options& options,
                        bool destroy_on_corruption,
                        Callbacks::InitStatusCallback callback) override;

  // Overrides for prepending namespace and type prefix to all operations on the
  // shared database.
  void UpdateEntries(std::unique_ptr<KeyValueVector> entries_to_save,
                     std::unique_ptr<KeyVector> keys_to_remove,
                     Callbacks::UpdateCallback callback) override;
  void UpdateEntriesWithRemoveFilter(
      std::unique_ptr<KeyValueVector> entries_to_save,
      const KeyFilter& delete_key_filter,
      Callbacks::UpdateCallback callback) override;
  void UpdateEntriesWithRemoveFilter(
      std::unique_ptr<KeyValueVector> entries_to_save,
      const KeyFilter& delete_key_filter,
      const std::string& target_prefix,
      Callbacks::UpdateCallback callback) override;

  void LoadEntries(Callbacks::LoadCallback callback) override;
  void LoadEntriesWithFilter(const KeyFilter& filter,
                             Callbacks::LoadCallback callback) override;
  void LoadEntriesWithFilter(const KeyFilter& key_filter,
                             const leveldb::ReadOptions& options,
                             const std::string& target_prefix,
                             Callbacks::LoadCallback callback) override;

  void LoadKeys(Callbacks::LoadKeysCallback callback) override;
  void LoadKeys(const std::string& target_prefix,
                Callbacks::LoadKeysCallback callback) override;

  void LoadKeysAndEntries(
      Callbacks::LoadKeysAndEntriesCallback callback) override;
  void LoadKeysAndEntriesWithFilter(
      const KeyFilter& filter,
      Callbacks::LoadKeysAndEntriesCallback callback) override;
  void LoadKeysAndEntriesWithFilter(
      const KeyFilter& filter,
      const leveldb::ReadOptions& options,
      const std::string& target_prefix,
      Callbacks::LoadKeysAndEntriesCallback callback) override;
  void LoadKeysAndEntriesInRange(
      const std::string& start,
      const std::string& end,
      Callbacks::LoadKeysAndEntriesCallback callback) override;
  void LoadKeysAndEntriesWhile(
      const std::string& start,
      const leveldb_proto::KeyIteratorController& controller,
      typename Callbacks::LoadKeysAndEntriesCallback callback) override;

  void GetEntry(const std::string& key,
                Callbacks::GetCallback callback) override;

  void Destroy(Callbacks::DestroyCallback callback) override;

  Callbacks::InitCallback GetInitCallback() const;

  const std::string& client_db_id() const { return prefix_.value(); }

  void set_migration_status(
      SharedDBMetadataProto::MigrationStatus migration_status) {
    migration_status_ = migration_status;
  }

  virtual void UpdateClientInitMetadata(SharedDBMetadataProto::MigrationStatus);

  SharedDBMetadataProto::MigrationStatus migration_status() const {
    return migration_status_;
  }

 private:
  friend class SharedProtoDatabase;
  friend class SharedProtoDatabaseTest;
  friend class SharedProtoDatabaseClientTest;
  friend class TestSharedProtoDatabaseClient;

  // Hide this so clients can only be created by the SharedProtoDatabase.
  SharedProtoDatabaseClient(
      std::unique_ptr<ProtoLevelDBWrapper> db_wrapper,
      ProtoDbType db_type,
      const scoped_refptr<SharedProtoDatabase>& parent_db);

  static void StripPrefixLoadKeysCallback(
      Callbacks::LoadKeysCallback callback,
      const KeyPrefix& prefix,
      bool success,
      std::unique_ptr<leveldb_proto::KeyVector> keys);
  static void StripPrefixLoadKeysAndEntriesCallback(
      Callbacks::LoadKeysAndEntriesCallback callback,
      const KeyPrefix& prefix,
      bool success,
      std::unique_ptr<KeyValueMap> keys_entries);

  static std::unique_ptr<KeyValueVector> PrefixKeyEntryVector(
      std::unique_ptr<KeyValueVector> kev,
      const KeyPrefix& prefix);

  SEQUENCE_CHECKER(sequence_checker_);

  // |is_corrupt_| should be set by the SharedProtoDatabase that creates this
  // when a client is created that doesn't know about a previous shared
  // database corruption.
  bool is_corrupt_ = false;
  SharedDBMetadataProto::MigrationStatus migration_status_ =
      SharedDBMetadataProto::MIGRATION_NOT_ATTEMPTED;

  const KeyPrefix prefix_;

  scoped_refptr<SharedProtoDatabase> parent_db_;

  base::WeakPtrFactory<SharedProtoDatabaseClient> weak_ptr_factory_{this};
};

}  // namespace leveldb_proto

#endif  // COMPONENTS_LEVELDB_PROTO_INTERNAL_SHARED_PROTO_DATABASE_CLIENT_H_