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_COMMIT_STORAGE_H
17 #define MULTI_VER_NATURAL_STORE_COMMIT_STORAGE_H
18 
19 #ifndef OMIT_MULTI_VER
20 #include <map>
21 #include <stack>
22 
23 #include "db_types.h"
24 #include "ikvdb.h"
25 #include "ikvdb_commit_storage.h"
26 #include "macro_utils.h"
27 
28 namespace DistributedDB {
29 class MultiVerNaturalStoreCommitStorage final : public IKvDBCommitStorage {
30 public:
31     MultiVerNaturalStoreCommitStorage();
32     ~MultiVerNaturalStoreCommitStorage() override;
33 
34     DISABLE_COPY_ASSIGN_MOVE(MultiVerNaturalStoreCommitStorage);
35 
36     int CheckVersion(const Property &property, bool &isDbExist) const override;
37 
38     int Open(const IKvDBCommitStorage::Property &property) override;
39 
40     void Close() override;
41 
42     int Remove(const IKvDBCommitStorage::Property &property) override;
43 
44     IKvDBCommit *AllocCommit(int &errCode) const override;
45 
46     IKvDBCommit *GetCommit(const CommitID &commitId, int &errCode) const override;
47 
48     int AddCommit(const IKvDBCommit &commitEntry, bool isHeader) override;
49     int RemoveCommit(const CommitID &commitId) override;
50 
51     void ReleaseCommit(const IKvDBCommit *commit) const override;
52 
53     int SetHeader(const CommitID &commitId) override;
54     CommitID GetHeader(int &errCode) const override;
55 
56     bool CommitExist(const CommitID &commitId, int &errCode) const override;
57 
58     int GetLatestCommits(std::map<DeviceID, IKvDBCommit *> &latestCommits) const override;
59 
60     Version GetMaxCommitVersion(int &errCode) const override;
61 
62     int GetCommitTree(const std::map<DeviceID, CommitID> &latestCommits,
63         std::list<IKvDBCommit *> &commits) const override;
64 
65     int RunRekeyLogic(CipherType type, const CipherPassword &passwd);
66 
67     int RunExportLogic(CipherType type, const CipherPassword &passwd, const std::string &dbDir);
68 
69     int BackupCurrentDatabase(const Property &property, const std::string &dir) override;
70 
71     int ImportDatabase(const Property &property, const std::string &dir, const CipherPassword &passwd) override;
72 
73     int StartVacuum() override;
74 
75     int CancelVacuum() override;
76 
77     int FinishVacuum() override;
78 
79     int GetAllCommitsInTree(std::list<MultiVerCommitNode> &commits) const override;
80 
81 private:
82     static void TransferCommitIDToKey(const CommitID &commitID, Key &key);
83 
84     static int TransferCommitToValue(const IKvDBCommit &commit, Value &value);
85     static int TransferValueToCommit(const Value &value, IKvDBCommit &commit);
86 
87     static void TransferStringToKey(const std::string &str, Key &key);
88 
89     static void TransferCommitIDToValue(const CommitID &commitID, Value &value);
90     static void TransferValueToCommitID(const Value &value, CommitID &commitID);
91 
92     static bool CompareCommit(const IKvDBCommit *first, const IKvDBCommit *second);
93 
94     static void GetLocalVersionThredForLatestCommits(const std::map<CommitID, IKvDBCommit *> &allCommits,
95         const std::map<DeviceID, CommitID> &latestCommits, std::map<DeviceID, Version> &latestCommitVersions);
96 
97     static void AddParentsToStack(const IKvDBCommit *commit,
98         const std::map<CommitID, IKvDBCommit *> &allCommits, std::stack<CommitID> &commitStack);
99 
100     static void RefreshCommitTree(std::list<IKvDBCommit *> &commits);
101 
102     int GetAllCommits(std::map<CommitID, IKvDBCommit *> &commits, CommitID &headerId) const;
103 
104     int SetHeaderInner(const CommitID &commitId);
105 
106     int CheckAddedCommit(const IKvDBCommit &commitEntry) const;
107 
108     // Release the latest commits for exception.
109     void ReleaseLatestCommits(std::map<DeviceID, IKvDBCommit *> &latestCommits) const;
110 
111     // Release the untraveled commits
112     void ReleaseUnusedCommits(std::map<CommitID, IKvDBCommit *> &commits) const;
113 
114     void ReleaseCommitList(std::list<IKvDBCommit *> &commits) const;
115 
116     static int GetVersion(const IKvDBCommitStorage::Property &property, int &version, bool &isDbExisted);
117 
118 private:
119     static const std::string HEADER_KEY;
120     std::string branchTag_;
121     IKvDB *commitStorageDatabase_;
122     IKvDBConnection *commitStorageDBConnection_;
123 };
124 } // namespace DistributedDB
125 
126 #endif // MULTI_VER_NATURAL_STORE_COMMIT_STORAGE_H
127 #endif