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