File: proto_database.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 (248 lines) | stat: -rw-r--r-- 10,529 bytes parent folder | download | duplicates (10)
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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
// Copyright 2014 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_PUBLIC_PROTO_DATABASE_H_
#define COMPONENTS_LEVELDB_PROTO_PUBLIC_PROTO_DATABASE_H_

#include <map>
#include <vector>

#include "base/component_export.h"
#include "base/task/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "third_party/leveldatabase/env_chromium.h"

namespace leveldb_proto {

class ProtoLevelDBWrapper;

class Enums {
 public:
  enum InitStatus {
    // Failed to migrate from shared to unique or unique to shared, or failed to
    // create a non-existent database.
    kError = -1,
    // Internal state, never returned to clients. TODO: This should be removed.
    kNotInitialized = 0,
    // Leveldb initialization successful.
    kOK = 1,
    // In case of unique database, this status is never returned. The legacy
    // behavior is to delete the database on corruption and return a clean one
    // (if possible). In case of shared database, the default behavior is to
    // delete on corruption and not return this flag. In the future we will have
    // a delete_on_corruption flag that clients can set to false and handle
    // corruption with partial data. TODO(salg): Expose delete_on_corruption
    // flag.
    kCorrupt = 2,
    // Invalid arguments were passed (like database doesn't exist and
    // create_if_missing was false), or the current platform does not support
    // leveldb.
    kInvalidOperation = 3,
  };
  enum KeyIteratorAction {
    // Load the current entry and continue scanning.
    kLoadAndContinue = 0,
    // Skip the current entry and continue scanning.
    kSkipAndContinue = 1,
    // Load the current entry and stop scanning.
    kLoadAndStop = 2,
    // Skip the current entry and stop scanning.
    kSkipAndStop = 3,
  };
};

class Callbacks {
 public:
  using InitCallback = base::OnceCallback<void(bool)>;
  using InitStatusCallback = base::OnceCallback<void(Enums::InitStatus)>;
  using UpdateCallback = base::OnceCallback<void(bool)>;
  using LoadKeysCallback =
      base::OnceCallback<void(bool, std::unique_ptr<std::vector<std::string>>)>;
  using DestroyCallback = base::OnceCallback<void(bool)>;
  using OnCreateCallback = base::OnceCallback<void(ProtoLevelDBWrapper*)>;

  // TODO(ssid): This should be moved to internal folder.
  using LoadCallback =
      base::OnceCallback<void(bool, std::unique_ptr<std::vector<std::string>>)>;
  using GetCallback =
      base::OnceCallback<void(bool, std::unique_ptr<std::string>)>;
  using LoadKeysAndEntriesCallback = base::OnceCallback<
      void(bool, std::unique_ptr<std::map<std::string, std::string>>)>;

  template <typename T>
  class Internal {
   public:
    using LoadCallback =
        base::OnceCallback<void(bool, std::unique_ptr<std::vector<T>>)>;
    using GetCallback = base::OnceCallback<void(bool, std::unique_ptr<T>)>;
    using LoadKeysAndEntriesCallback =
        base::OnceCallback<void(bool,
                                std::unique_ptr<std::map<std::string, T>>)>;
  };
};

class Util {
 public:
  template <typename T>
  class Internal {
   public:
    // A list of key-value (string, T) tuples.
    using KeyEntryVector = std::vector<std::pair<std::string, T>>;
  };
};

//  When used to filter keys, a key is skipped skipped if the callback returns
//  `false`. When used to control a while loop, the loop is stopped if the
//  callback returns `false`.
using KeyFilter = base::RepeatingCallback<bool(const std::string& key)>;

// Callback choosing the next action when scanning the database.
using KeyIteratorController =
    base::RepeatingCallback<Enums::KeyIteratorAction(const std::string& key)>;

// Interface for classes providing persistent storage of Protocol Buffer
// entries. P must be a proto type extending MessageLite. T is optional and
// defaults to P and there is then no additional requirements for clients.
// If T is set to something else, the client must provide these functions
// (note the namespace requirement):
//    namespace leveldb_proto {
//    void DataToProto(const T& data, P* proto);
//    void ProtoToData(const P& proto, T* data);
//    }  // namespace leveldb_proto
//
// The P type will be stored in the database, and the T type will be required
// as input and will be provided as output for all API calls. The backend will
// invoke the methods above for all conversions between the two types.
//
// For retrieving a database of proto type ClientProto, use:
//    auto db = ProtoDatabaseProviderFactory::GetForBrowserContext(...)
//        -> GetDB<ClientProto>(...);
//
// For automatically converting to a different data type, use:
//    auto db = ProtoDatabaseProviderFactory::GetForBrowserContext(...)
//        -> GetDB<ClientProto, ClientStruct>(...);
template <typename P, typename T = P>
class ProtoDatabase {
 public:
  // For compatibility:
  using KeyEntryVector = typename Util::Internal<T>::KeyEntryVector;

  virtual ~ProtoDatabase() = default;

  // Asynchronously initializes the object, which must have been created by the
  // ProtoDatabaseProvider::GetDB<T> function. |callback| will be invoked on the
  // calling thread when complete.
  //
  // DEPRECATED: |unique_db_options| is used only when a unique DB is loaded,
  // once migration to shared DB is done, this parameter will be ignored.
  virtual void Init(Callbacks::InitStatusCallback callback) = 0;
  virtual void Init(const leveldb_env::Options& unique_db_options,
                    Callbacks::InitStatusCallback callback) = 0;

  // Asynchronously saves |entries_to_save| and deletes entries from
  // |keys_to_remove| from the database. |callback| will be invoked on the
  // calling thread when complete. |entries_to_save| and |keys_to_remove| must
  // be non-null.
  virtual 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) = 0;

  // Asynchronously deletes entries that satisfies the |delete_key_filter|
  // from the database, and saves |entries_to_save|. |entries_to_save| will not
  // be deleted if they match |delete_key_filter|. |callback| will be invoked on
  // the calling thread when complete. The filter will be called on
  // ProtoDatabase's taskrunner. |entries_to_save| must be non-null.
  virtual void UpdateEntriesWithRemoveFilter(
      std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
          entries_to_save,
      const leveldb_proto::KeyFilter& delete_key_filter,
      Callbacks::UpdateCallback callback) = 0;

  // Asynchronously loads all entries from the database and invokes |callback|
  // when complete.
  virtual void LoadEntries(
      typename Callbacks::Internal<T>::LoadCallback callback) = 0;

  // Asynchronously loads entries that satisfies the |filter| from the database
  // and invokes |callback| when complete. The filter will be called on
  // ProtoDatabase's taskrunner.
  virtual void LoadEntriesWithFilter(
      const leveldb_proto::KeyFilter& filter,
      typename Callbacks::Internal<T>::LoadCallback callback) = 0;
  virtual void LoadEntriesWithFilter(
      const leveldb_proto::KeyFilter& key_filter,
      const leveldb::ReadOptions& options,
      const std::string& target_prefix,
      typename Callbacks::Internal<T>::LoadCallback callback) = 0;

  virtual void LoadKeysAndEntries(
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) = 0;

  virtual void LoadKeysAndEntriesWithFilter(
      const leveldb_proto::KeyFilter& filter,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) = 0;
  virtual void LoadKeysAndEntriesWithFilter(
      const leveldb_proto::KeyFilter& filter,
      const leveldb::ReadOptions& options,
      const std::string& target_prefix,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) = 0;

  // Asynchronously loads entries and their keys for keys in range [start, end]
  // (both inclusive) and invokes |callback| when complete.
  //
  // Range is defined as |start| <= returned keys <= |end|.
  // When |start| = 'bar' and |end| = 'foo' then the keys within brackets are
  // returned: baa, [bar, bara, barb, foa, foo], fooa, fooz, fop.
  virtual void LoadKeysAndEntriesInRange(
      const std::string& start,
      const std::string& end,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) = 0;

  // Asynchronously loads entries and their keys iterating in lexicographical
  // order.
  //
  // For each encountered key the |controller| dictates the next action:
  //    - Should the entry corresponding to the current key should be loaded?
  //    - Should the sequential scanning of the db continue?
  //
  // The first processed key is equal to or greater than |start|. Unless
  // interrupted, loads keys until the last entry in the database. Invokes
  // |callback| when complete.
  virtual void LoadKeysAndEntriesWhile(
      const std::string& start,
      const leveldb_proto::KeyIteratorController& controller,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) = 0;

  // Asynchronously loads all keys from the database and invokes |callback| with
  // those keys when complete.
  virtual void LoadKeys(typename Callbacks::LoadKeysCallback callback) = 0;

  // Asynchronously loads a single entry, identified by |key|, from the database
  // and invokes |callback| when complete. If no entry with |key| is found,
  // a nullptr is passed to the callback, but the success flag is still true.
  virtual void GetEntry(
      const std::string& key,
      typename Callbacks::Internal<T>::GetCallback callback) = 0;

  // Asynchronously destroys the database. Use this call only if the database
  // needs to be destroyed for this particular profile. If the database is no
  // longer useful for everyone, the client name must be added to
  // |kObsoleteSharedProtoDatabaseClients| to ensure automatic clean up of the
  // database from all users.
  virtual void Destroy(Callbacks::DestroyCallback callback) = 0;

 protected:
  ProtoDatabase() = default;
};

// Return a new instance of Options, but with two additions:
// 1) create_if_missing = true
// 2) max_open_files = 0
leveldb_env::Options COMPONENT_EXPORT(LEVELDB_PROTO) CreateSimpleOptions();

}  // namespace leveldb_proto

#endif  // COMPONENTS_LEVELDB_PROTO_PUBLIC_PROTO_DATABASE_H_