1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef MULTI_VER_NATURAL_STORE_H
17 #define MULTI_VER_NATURAL_STORE_H
18 
19 #ifndef OMIT_MULTI_VER
20 #include "sync_able_kvdb.h"
21 #include "multi_ver_kvdb_sync_interface.h"
22 #include "kv_store_changed_data.h"
23 #include "ikvdb_multi_ver_data_storage.h"
24 #include "ikvdb_commit_storage.h"
25 #include "macro_utils.h"
26 #include "multi_ver_kvdata_storage.h"
27 #include "multi_ver_storage_executor.h"
28 #include "multi_ver_storage_engine.h"
29 #include "multi_ver_vacuum.h"
30 
31 namespace DistributedDB {
32 enum NaturalStoreNotificationEventType {
33     NATURAL_STORE_COMMIT_EVENT = 0
34 };
35 class MultiVerVacuumExecutorImpl;
36 class MultiVerNaturalStore final: public SyncAbleKvDB, public MultiVerKvDBSyncInterface {
37 public:
38     MultiVerNaturalStore();
39     ~MultiVerNaturalStore() override;
40 
41     // Delete the copy and assign constructors
42     DISABLE_COPY_ASSIGN_MOVE(MultiVerNaturalStore);
43 
44     // Open the database
45     int Open(const KvDBProperties &kvDBProp) override;
46 
47     // Invoked automatically when connection count is zero
48     void Close() override;
49 
50     // Create a connection object.
51     GenericKvDBConnection *NewConnection(int &errCode) override;
52 
53     // Get interface for syncer.
54     IKvDBSyncInterface *GetSyncInterface() override;
55 
56     // Get interface type of this kvdb.
57     int GetInterfaceType() const override;
58 
59     // Get the interface ref-count, in order to access asynchronously.
60     void IncRefCount() override;
61 
62     // Drop the interface ref-count.
63     void DecRefCount() override;
64 
65     // Get the identifier of this kvdb.
66     std::vector<uint8_t> GetIdentifier() const override;
67 
68     // Get the max timestamp of all entries in database.
69     void GetMaxTimestamp(Timestamp &stamp) const override;
70 
71     // Get meta data associated with the given key.
72     int GetMetaData(const Key &key, Value &value) const override;
73 
74     // Put meta data as a key-value entry.
75     int PutMetaData(const Key &key, const Value &value, bool isInTransaction) override;
76 
77     // Delete multiple meta data records in a transaction.
78     int DeleteMetaData(const std::vector<Key> &keys) override;
79     // Delete multiple meta data records with key prefix in a transaction.
80     int DeleteMetaDataByPrefixKey(const Key &keyPrefix) const override;
81 
82     // Get all meta data keys.
83     int GetAllMetaKeys(std::vector<Key> &keys) const override;
84 
85     bool IsCommitExisted(const MultiVerCommitNode &commit) const override;
86 
87     int GetDeviceLatestCommit(std::map<std::string, MultiVerCommitNode> &) const override;
88 
89     int GetCommitTree(const std::map<std::string, MultiVerCommitNode> &,
90         std::vector<MultiVerCommitNode> &) const override;
91 
92     int GetCommitData(const MultiVerCommitNode &commit, std::vector<MultiVerKvEntry *> &entries) const override;
93 
94     MultiVerKvEntry *CreateKvEntry(const std::vector<uint8_t> &data) override;
95 
96     void ReleaseKvEntry(const MultiVerKvEntry *entry) override;
97 
98     bool IsValueSliceExisted(const ValueSliceHash &value) const override;
99 
100     int GetValueSlice(const ValueSliceHash &hashValue, ValueSlice &sliceValue) const override;
101 
102     int PutValueSlice(const ValueSliceHash &hashValue, const ValueSlice &sliceValue) const override;
103 
104     int PutCommitData(const MultiVerCommitNode &commit, const std::vector<MultiVerKvEntry *> &entries,
105         const std::string &deviceName) override;
106 
107     int MergeSyncCommit(const MultiVerCommitNode &commit, const std::vector<MultiVerCommitNode> &commits) override;
108 
109     void NotifyStartSyncOperation() override;
110 
111     void NotifyFinishSyncOperation() override;
112 
113     int TransferSyncCommitDevInfo(MultiVerCommitNode &commit, const std::string &devId, bool isSyncedIn) const override;
114 
115     int Rekey(const CipherPassword &passwd) override;
116 
117     int Export(const std::string &filePath, const CipherPassword &passwd) override;
118 
119     int Import(const std::string &filePath, const CipherPassword &passwd) override;
120 
121     int GetDiffEntries(const CommitID &begin, const CommitID &end, MultiVerDiffData &data) const;
122 
123     uint64_t GetCurrentTimestamp();
124 
125     // Set the max timestamp
126     void SetMaxTimestamp(Timestamp stamp);
127 
128     Version GetMaxCommitVersion() const;
129 
130     void SetMaxCommitVersion(const Version &version);
131 
132     MultiVerStorageExecutor *GetHandle(bool isWrite, int &errCode,
133         bool isTrimming = false, OperatePerm perm = OperatePerm::NORMAL_PERM) const;
134 
135     void ReleaseHandle(MultiVerStorageExecutor *&handle, bool isTrimming = false) const;
136 
137     void GetCurrentTag(std::vector<uint8_t> &tag) const;
138 
139     // Just provide the version constraint for trimmming data(include observer and the snapshot)
140     void AddVersionConstraintToList(Version version);
141 
142     void RemoveVersionConstraintFromList(Version version);
143 
144     // Get the max trimmable version, if no need trimming, return 0; if need trimming all return the MAX_UINT64.
145     Version GetMaxTrimmableVersion() const;
146 
147     int TransObserverTypeToRegisterFunctionType(int observerType, RegisterFuncType &type) const override;
148 
149     const KvDBProperties &GetDbProperties() const override;
150 
151     int RemoveKvDB(const KvDBProperties &properties) override;
152 
153     int GetKvDBSize(const KvDBProperties &properties, uint64_t &size) const override;
154 
155     KvDBProperties &GetDbPropertyForUpdate();
156 
157     int InitStorages(const KvDBProperties &kvDBProp, bool isChangeTag = false);
158 
159     void SetSendDataInterceptor(const PushDataInterceptor &interceptor) override;
160 
161     void SetReceiveDataInterceptor(const DataInterceptor &interceptor) override;
162 
163 private:
164 
165     int CheckSubStorageVersion(const KvDBProperties &kvDBProp, bool &isSubStorageAllExist) const;
166 
167     int CreateStorages();
168 
169     int CreateStoreDirectory(const std::string &directory, const std::string &identifierName);
170 
171     void Clear();
172 
173     int RecoverFromException();
174 
175     int CompareVerDataAndLog(IKvDBMultiVerTransaction *transaction) const;
176 
177     int ClearTempFile(const KvDBProperties &kvDBProp);
178 
179     int InitStorageContext(bool isChangeTag);
180 
181     int InitStorageContextVersion(bool isChangeTag);
182 
183     std::string GetStringIdentifier() const;
184 
185     int CheckVersion(const KvDBProperties &kvDBProp) const;
186 
187     int CheckOverallVersionViaVersionFile(const KvDBProperties &kvDBProp, bool &isVerFileExist) const;
188 
189     int GetVersionFilePath(const KvDBProperties &kvDBProp, std::string &outPath) const;
190 
191     DECLARE_OBJECT_TAG(MultiVerNaturalStore);
192 
193     static MultiVerVacuum shadowTrimmer_;
194     IKvDBMultiVerDataStorage *multiVerData_;
195     IKvDBCommitStorage *commitHistory_;
196     MultiVerKvDataStorage *multiVerKvStorage_;
197     std::unique_ptr<MultiVerStorageEngine> multiVerEngine_;
198     MultiVerVacuumExecutorImpl *trimmerImpl_;
199     mutable std::mutex commitHistMutex_;
200     mutable std::mutex multiDataMutex_;
201     mutable std::mutex syncerKvMutex_;
202     mutable std::mutex maxTimeMutex_;
203     mutable std::mutex versionConstraintMutex_;
204     mutable uint64_t maxRecordTimestamp_;
205     Version maxCommitVersion_;
206     std::vector<uint8_t> branchTag_;
207     std::multiset<Version> versionConstraints_;
208 };
209 } // namespace DistributedDB
210 
211 #endif  // MULTI_VER_NATURAL_STORE_H
212 #endif