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 SINGLE_VER_NATURAL_STORE_COMMIT_NOTIFY_DATA_H
17 #define SINGLE_VER_NATURAL_STORE_COMMIT_NOTIFY_DATA_H
18 
19 #include "kvdb_commit_notify_filterable_data.h"
20 
21 namespace DistributedDB {
22 enum class DataType {
23     NONE,
24     INSERT,
25     UPDATE,
26     DELETE,
27 };
28 
29 enum class ExistStatus {
30     NONE, // key never exist in db
31     DELETED, // key deleted but exist before
32     EXIST, // key exist
33 };
34 constexpr size_t MAX_TOTAL_NOTIFY_ITEM_SIZE = 1048576; // 1MB
35 constexpr size_t MAX_TOTAL_NOTIFY_DATA_SIZE = 4195328; // 4MB + 1KB
36 
37 struct DataItemInfo {
38     DataItem dataItem;
39     bool isLocal = false;
40     std::vector<uint8_t> deviceName;
41 };
42 
43 class SingleVerNaturalStoreCommitNotifyData final : public KvDBCommitNotifyFilterAbleData {
44 public:
45     SingleVerNaturalStoreCommitNotifyData();
~SingleVerNaturalStoreCommitNotifyData()46     ~SingleVerNaturalStoreCommitNotifyData() {}
47     DISABLE_COPY_ASSIGN_MOVE(SingleVerNaturalStoreCommitNotifyData);
48 
49     const std::list<Entry> GetInsertedEntries(int &errCode) const override;
50 
51     const std::list<Entry> GetUpdatedEntries(int &errCode) const override;
52 
53     const std::list<Entry> GetDeletedEntries(int &errCode) const override;
54 
55     const std::list<KvDBConflictEntry> GetCommitConflicts(int &errCode) const override;
56 
57     void SetFilterKey(const Key &key) override;
58 
59     bool IsChangedDataEmpty() const override;
60 
61     bool IsConflictedDataEmpty() const override;
62 
63     int InsertCommittedData(const Entry &entry, DataType dataType, bool needMerge = false);
64 
65     int InsertConflictedItem(const DataItemInfo &itemInfo, bool isOriginal = false);
66 
67     void InitKeyPropRecord(const Key &key, ExistStatus status);
68 
69     void SetConflictedNotifiedFlag(int conflictedFlag);
70 
71     int GetConflictedNotifiedFlag() const;
72 
73     bool IsConflictedNotifyMatched(const DataItem &itemPut, const DataItem &itemGet) const;
74 
75 private:
76 
77     struct ItemProp {
78         ExistStatus existStatus = ExistStatus::NONE; // indicator if the key exist in db before this transaction
79         DataType latestType = DataType::NONE; // indicator the latest operation type for this key
80     };
81 
82     int InsertEntry(DataType dataType, const Entry &entry);
83 
84     static const std::list<Entry> FilterEntriesByKey(const std::list<Entry> &entries,
85         const Key &filterKey, int &errCode);
86 
87     void DeleteEntry(const Key &key, std::list<Entry> &entries) const;
88 
89     void DeleteEntryByKey(const Key &key, DataType type);
90 
91     void PutIntoConflictData(const DataItemInfo &orgItemInfo, const DataItemInfo &newItemInfo);
92 
93     void DeleteConflictEntry(const Key &key);
94 
95     bool IsKeyPropSet(const Key &key) const;
96 
97     DECLARE_OBJECT_TAG(SingleVerNaturalStoreCommitNotifyData);
98 
99     static const int SINGLE_VER_CONFLICT_FOREIGN_KEY_ONLY = 0x01; // sync conflict for same origin dev
100     static const int SINGLE_VER_CONFLICT_FOREIGN_KEY_ORIG = 0x02; // sync conflict for different origin dev
101     static const int SINGLE_VER_CONFLICT_NATIVE_ALL = 0x0c;       // native conflict.
102 
103     std::list<Entry> insertedEntries_;
104     std::list<Entry> updatedEntries_;
105     std::list<Entry> deletedEntries_;
106     std::list<KvDBConflictEntry> conflictedEntries_;
107     Key keyFilter_;
108     std::map<Key, ItemProp> keyPropRecord_; // hash key mapping to item property
109     std::map<Key, DataItemInfo> orgDataItem_;
110     int conflictedFlag_; // the conflict notifier type composition, 0 means no conflict notifier.
111 };
112 } // namespace DistributedDB
113 
114 #endif // SINGLE_VER_NATURAL_STORE_COMMIT_NOTIFY_DATA_H