1 /* 2 * Copyright (c) 2022 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 #ifndef OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H 16 #define OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H 17 #include <map> 18 #include <mutex> 19 20 #include "eventcenter/event.h" 21 #include "executor_pool.h" 22 #include "lru_bucket.h" 23 #include "matrix_event.h" 24 #include "metadata/matrix_meta_data.h" 25 #include "metadata/store_meta_data.h" 26 #include "utils/ref_count.h" 27 #include "visibility.h" 28 29 namespace OHOS::DistributedData { 30 class API_EXPORT DeviceMatrix { 31 public: 32 using TimePoint = std::chrono::steady_clock::time_point; 33 using Origin = OHOS::DistributedData::MatrixMetaData::Origin; 34 static constexpr uint16_t META_STORE_MASK = 0x0001; 35 static constexpr uint16_t INVALID_HIGH = 0xFFF0; 36 static constexpr uint16_t INVALID_LEVEL = 0xFFFF; 37 static constexpr uint16_t INVALID_LENGTH = 0; 38 static constexpr uint32_t INVALID_VALUE = 0xFFFFFFFF; 39 static constexpr uint16_t INVALID_MASK = 0; 40 enum : int32_t { 41 MATRIX_ONLINE = Event::EVT_CUSTOM, 42 MATRIX_META_FINISHED, 43 MATRIX_BROADCAST, 44 MATRIX_BUTT 45 }; 46 enum LevelType : int32_t { 47 STATICS = 0, 48 DYNAMIC, 49 BUTT, 50 }; 51 enum ChangeType : uint32_t { 52 CHANGE_LOCAL = 0x1, 53 CHANGE_REMOTE = 0x2, 54 CHANGE_ALL = 0x3, 55 CHANGE_BUTT 56 }; 57 struct DataLevel { 58 uint16_t dynamic = INVALID_LEVEL; 59 uint16_t statics = INVALID_LEVEL; 60 uint32_t switches = INVALID_VALUE; 61 uint16_t switchesLen = INVALID_LENGTH; 62 bool IsValid() const; 63 }; 64 65 static DeviceMatrix &GetInstance(); 66 bool Initialize(uint32_t token, std::string storeId); 67 void Online(const std::string &device, RefCount refCount = {}); 68 void Offline(const std::string &device); 69 std::pair<uint16_t, uint16_t> OnBroadcast(const std::string &device, const DataLevel &dataLevel); 70 void Broadcast(const DataLevel &dataLevel); 71 void OnChanged(uint16_t code, LevelType type = LevelType::DYNAMIC); 72 void OnChanged(const StoreMetaData &metaData); 73 void OnExchanged(const std::string &device, uint16_t code, 74 LevelType type = LevelType::DYNAMIC, ChangeType changeType = ChangeType::CHANGE_ALL); 75 void OnExchanged(const std::string &device, 76 const StoreMetaData &metaData, ChangeType type = ChangeType::CHANGE_ALL); 77 void UpdateLevel(const std::string &device, uint16_t level, LevelType type, bool isConsistent = false); 78 void Clear(); 79 void SetExecutor(std::shared_ptr<ExecutorPool> executors); 80 uint16_t GetCode(const StoreMetaData &metaData); 81 std::pair<bool, uint16_t> GetMask(const std::string &device, LevelType type = LevelType::DYNAMIC); 82 std::pair<bool, uint16_t> GetRemoteMask(const std::string &device, LevelType type = LevelType::DYNAMIC); 83 std::pair<bool, uint16_t> GetRecvLevel(const std::string &device, LevelType type); 84 std::pair<bool, uint16_t> GetConsLevel(const std::string &device, LevelType type); 85 std::pair<bool, bool> IsConsistent(const std::string &device); 86 std::pair<bool, MatrixMetaData> GetMatrixMeta(const std::string &device, bool isConsistent = false); 87 std::map<std::string, uint16_t> GetRemoteDynamicMask(); 88 bool IsDynamic(const StoreMetaData &metaData); 89 bool IsStatics(const StoreMetaData &metaData); 90 bool IsSupportMatrix(); 91 bool IsConsistent(); 92 93 private: 94 static constexpr uint32_t RESET_MASK_DELAY = 10; // min 95 static constexpr uint32_t CURRENT_VERSION = 3; 96 static constexpr uint16_t CURRENT_DYNAMIC_MASK = 0x0006; 97 static constexpr uint16_t CURRENT_STATICS_MASK = 0x0003; 98 static constexpr size_t MAX_DEVICES = 64; 99 100 DeviceMatrix(); 101 ~DeviceMatrix(); 102 DeviceMatrix(const DeviceMatrix &) = delete; 103 DeviceMatrix(DeviceMatrix &&) noexcept = delete; 104 DeviceMatrix &operator=(const DeviceMatrix &) = delete; 105 DeviceMatrix &operator=(DeviceMatrix &&) noexcept = delete; SetMask(size_t index)106 static inline uint16_t SetMask(size_t index) 107 { 108 return 0x1 << index; 109 } Low(uint16_t data)110 static inline uint16_t Low(uint16_t data) 111 { 112 return data & 0x000F; 113 } High(uint16_t data)114 static inline uint16_t High(uint16_t data) 115 { 116 return data & 0xFFF0; 117 } Merge(uint16_t high,uint16_t low)118 static inline uint16_t Merge(uint16_t high, uint16_t low) 119 { 120 return High(high) | Low(low); 121 } ResetMask(uint16_t data)122 static inline uint16_t ResetMask(uint16_t data) 123 { 124 return data &= 0xFFF0; 125 } 126 struct Mask { 127 uint16_t dynamic = META_STORE_MASK | CURRENT_DYNAMIC_MASK; 128 uint16_t statics = CURRENT_STATICS_MASK; 129 void SetDynamicMask(uint16_t mask); 130 void SetStaticsMask(uint16_t mask); 131 }; 132 using TaskId = ExecutorPool::TaskId; 133 using Task = ExecutorPool::Task; 134 135 void UpdateMask(Mask &mask); 136 void UpdateConsistentMeta(const std::string &device, const Mask &remote); 137 void SaveSwitches(const std::string &device, const DataLevel &dataLevel); 138 void UpdateRemoteMeta(const std::string &device, Mask &mask, MatrixMetaData &newMeta); 139 Task GenResetTask(); 140 std::pair<uint16_t, uint16_t> ConvertMask(const std::string &device, const DataLevel &dataLevel); 141 uint16_t ConvertDynamic(const MatrixMetaData &meta, uint16_t mask); 142 uint16_t ConvertStatics(const MatrixMetaData &meta, uint16_t mask); 143 MatrixMetaData GetMatrixInfo(const std::string &device); 144 MatrixMetaData GetMatrixMetaData(const std::string &device, const Mask &mask); 145 static inline uint16_t ConvertIndex(uint16_t code); 146 147 MatrixEvent::MatrixData lasts_; 148 std::mutex taskMutex_; 149 std::shared_ptr<ExecutorPool> executors_; 150 TaskId task_ = ExecutorPool::INVALID_TASK_ID; 151 152 bool isSupportBroadcast_ = true; 153 uint32_t tokenId_ = 0; 154 std::string storeId_; 155 std::mutex mutex_; 156 std::map<std::string, Mask> onLines_; 157 std::map<std::string, Mask> offLines_; 158 std::map<std::string, Mask> remotes_; 159 std::vector<std::string> dynamicApps_; 160 std::vector<std::string> staticsApps_; 161 std::function<void(bool, bool)> observer_; 162 LRUBucket<std::string, MatrixMetaData> matrices_{ MAX_DEVICES }; 163 LRUBucket<std::string, MatrixMetaData> versions_{ MAX_DEVICES }; 164 }; 165 } // namespace OHOS::DistributedData 166 #endif // OHOS_DISTRIBUTED_DATA_SERVICE_MATRIX_DEVICE_MATRIX_H