1 /*
2  * Copyright (c) 2023 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 OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H
17 #define OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H
18 
19 #include <functional>
20 #include <memory>
21 #include <unordered_map>
22 #include "hdf_log.h"
23 #include "nocopyable.h"
24 #include <mutex>
25 
26 #undef LOG_TAG
27 #define LOG_TAG "DISP_CACHE_MGR"
28 #undef LOG_DOMAIN
29 #define LOG_DOMAIN 0xD002515
30 
31 namespace OHOS {
32 namespace HDI {
33 namespace Display {
34 namespace Composer {
35 
36 template <typename IdType, typename CacheType>
37 class CacheManager : public NoCopyable {
38 public:
CacheManager()39     CacheManager()
40         : cacheCountMax_ { 0 },
41           cleanUpFunc_ { nullptr },
42           initFunc_ { nullptr }
43     {}
44 
~CacheManager()45     virtual ~CacheManager()
46     {
47         std::lock_guard<std::mutex> lock(mutex_);
48         if (cleanUpFunc_) {
49             for (auto& cache : caches_) {
50                 cleanUpFunc_(cache.second);
51             }
52         }
53         caches_.clear();
54     }
55 
SetCacheMaxCount(uint32_t count)56     bool SetCacheMaxCount(uint32_t count)
57     {
58         bool ret = true;
59         uint32_t originalMaxCount = cacheCountMax_;
60         if (count >= cacheCountMax_) {
61             cacheCountMax_ = count;
62         } else if (Size() <= count) {
63             cacheCountMax_ = count;
64         } else {
65             HDF_LOGE("%{public}s error: clientCacheCount can't be set, because cacheCountMax_ > count", __func__);
66             ret = false;
67         }
68         HDF_LOGD("%{public}s: set cache max count from %{public}u to %{public}u",
69             __func__, originalMaxCount, cacheCountMax_);
70         return ret;
71     }
72 
Size()73     uint32_t Size()
74     {
75         std::lock_guard<std::mutex> lock(mutex_);
76         return caches_.size();
77     }
78 
InsertCache(IdType id,CacheType * cache)79     bool InsertCache(IdType id, CacheType* cache)
80     {
81         std::lock_guard<std::mutex> lock(mutex_);
82         auto cacheItem = caches_.find(id);
83         if (cacheItem != caches_.end()) {
84             HDF_LOGI("%{public}s: intend to insert a existing cache, SeqNo=%{public}d", __func__, id);
85             cacheItem->second.reset(cache);
86         } else {
87             if (cacheCountMax_ != 0 && caches_.size() >= cacheCountMax_) {
88                 HDF_LOGE("%{public}s: Caches is full, new seqNo:%{public}d can't be inserted", __func__, id);
89                 return false;
90             }
91             caches_[id] = std::move(std::unique_ptr<CacheType>(cache));
92         }
93         if (initFunc_) {
94             initFunc_(caches_[id]);
95         }
96         return true;
97     }
98 
EraseCache(IdType id)99     bool EraseCache(IdType id)
100     {
101         std::lock_guard<std::mutex> lock(mutex_);
102         auto cacheItem = caches_.find(id);
103         if (cacheItem == caches_.end()) {
104             return false;
105         }
106 
107         if (cleanUpFunc_ && cacheItem->second != nullptr) {
108             cleanUpFunc_(cacheItem->second);
109         }
110 
111         caches_.erase(cacheItem);
112         return true;
113     }
114 
SearchCache(IdType id)115     CacheType* SearchCache(IdType id)
116     {
117         std::lock_guard<std::mutex> lock(mutex_);
118         auto cacheItem = caches_.find(id);
119         if (cacheItem == caches_.end()) {
120             return nullptr;
121         }
122 
123         return cacheItem->second.get();
124     }
125 
TravelCaches(std::function<void (IdType id,const CacheType & cache)> func)126     void TravelCaches(std::function<void (IdType id, const CacheType& cache)> func)
127     {
128         std::lock_guard<std::mutex> lock(mutex_);
129         for (auto const& [key, value] : caches_) {
130             func(key, *value.get());
131         }
132     }
133 
SetCleanUpFunc(void (* func)(std::unique_ptr<CacheType> &))134     void SetCleanUpFunc(void (*func)(std::unique_ptr<CacheType>&))
135     {
136         cleanUpFunc_ = func;
137     }
138 
SetInitFunc(void (* func)(std::unique_ptr<CacheType> &))139     void SetInitFunc(void (*func)(std::unique_ptr<CacheType>&))
140     {
141         initFunc_ = func;
142     }
143 
144 private:
145     uint32_t cacheCountMax_;
146     std::unordered_map<IdType, std::unique_ptr<CacheType>> caches_;
147     void (*cleanUpFunc_)(std::unique_ptr<CacheType>&);
148     void (*initFunc_)(std::unique_ptr<CacheType>&);
149     std::mutex mutex_;
150 };
151 } // namespace Composer
152 } // namespace Display
153 } // namespace HDI
154 } // namespace OHOS
155 #endif // OHOS_HDI_DISPLAY_V1_0_CACHE_MANAGER_H
156