• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_IMAGE_CACHE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_IMAGE_CACHE_H
18 
19 #include <algorithm>
20 #include <list>
21 #include <mutex>
22 #include <shared_mutex>
23 #include <unordered_map>
24 #include <utility>
25 #include <vector>
26 
27 #include "base/image/pixel_map.h"
28 #include "base/log/log.h"
29 #include "base/memory/ace_type.h"
30 #include "base/utils/macros.h"
31 
32 namespace OHOS::Ace {
33 
34 struct CachedImage;
35 class ImageObject;
36 
37 namespace NG {
38 struct CachedImage;
39 class ImageObject;
40 } // namespace NG
41 
42 template<typename T>
43 struct CacheNode {
CacheNodeCacheNode44     CacheNode(std::string key, const T& obj) : cacheKey(std::move(key)), cacheObj(obj) {}
45     std::string cacheKey;
46     T cacheObj;
47 };
48 
49 struct CachedImageData : public AceType {
50     DECLARE_ACE_TYPE(CachedImageData, AceType);
51 
52 public:
53     CachedImageData() = default;
54     virtual ~CachedImageData() = default;
55     virtual size_t GetSize() = 0;
56     virtual const uint8_t* GetData() = 0;
57 };
58 
59 struct CacheImageDataNode {
CacheImageDataNodeCacheImageDataNode60     CacheImageDataNode(const std::string& key, const RefPtr<CachedImageData>& imageData)
61         : imageDataKey(key), imageDataPtr(imageData)
62     {}
63     std::string imageDataKey;
64     RefPtr<CachedImageData> imageDataPtr;
65 };
66 
67 struct FileInfo {
FileInfoFileInfo68     FileInfo(std::string path, size_t size, time_t time) : filePath(std::move(path)), fileSize(size), accessTime(time)
69     {}
70 
71     // file information will be sort by access time.
72     bool operator<(const FileInfo& otherFile) const
73     {
74         return accessTime < otherFile.accessTime;
75     }
76     std::string filePath;
77     size_t fileSize;
78     time_t accessTime;
79 };
80 
81 class ACE_EXPORT ImageCache : public AceType {
82     DECLARE_ACE_TYPE(ImageCache, AceType);
83 
84 public:
85     static RefPtr<ImageCache> Create();
86     ImageCache() = default;
87     ~ImageCache() override = default;
88 
89     void CacheImage(const std::string& key, const std::shared_ptr<CachedImage>& image);
90     void CacheImageNG(const std::string& key, const std::shared_ptr<NG::CachedImage>& image);
91     std::shared_ptr<CachedImage> GetCacheImage(const std::string& key);
92     std::shared_ptr<NG::CachedImage> GetCacheImageNG(const std::string& key);
93 
94     void CacheImageData(const std::string& key, const RefPtr<CachedImageData>& imageData);
95     RefPtr<CachedImageData> GetCacheImageData(const std::string& key);
96 
97     // cache interface for [NG::ImageObject]
98     RefPtr<NG::ImageObject> GetCacheImgObjNG(const std::string& key);
99     void CacheImgObjNG(const std::string& key, const RefPtr<NG::ImageObject>& imgObj);
100 
101     void CacheImgObj(const std::string& key, const RefPtr<ImageObject>& imgObj);
102     RefPtr<ImageObject> GetCacheImgObj(const std::string& key);
103 
104     static void SetCacheFileInfo();
105     static void WriteCacheFile(
106         const std::string& url, const void* data, size_t size, const std::string& suffix = std::string());
107 
SetCapacity(size_t capacity)108     void SetCapacity(size_t capacity)
109     {
110         LOGI("Set Capacity : %{public}d", static_cast<int32_t>(capacity));
111         capacity_ = capacity;
112     }
113 
SetDataCacheLimit(size_t sizeLimit)114     void SetDataCacheLimit(size_t sizeLimit)
115     {
116         LOGI("Set data size cache limit : %{public}d", static_cast<int32_t>(sizeLimit));
117         dataSizeLimit_ = sizeLimit;
118     }
119 
GetCapacity()120     size_t GetCapacity() const
121     {
122         return capacity_;
123     }
124 
GetCachedImageCount()125     size_t GetCachedImageCount() const
126     {
127         std::lock_guard<std::mutex> lock(imageCacheMutex_);
128         return cacheList_.size();
129     }
130 
SetImageCacheFilePath(const std::string & cacheFilePath)131     static void SetImageCacheFilePath(const std::string& cacheFilePath)
132     {
133         std::unique_lock<std::shared_mutex> lock(cacheFilePathMutex_);
134         if (cacheFilePath_.empty()) {
135             cacheFilePath_ = cacheFilePath;
136         }
137     }
138 
GetImageCacheFilePath()139     static std::string GetImageCacheFilePath()
140     {
141         std::shared_lock<std::shared_mutex> lock(cacheFilePathMutex_);
142         return cacheFilePath_;
143     }
144 
GetImageCacheFilePath(const std::string & url)145     static std::string GetImageCacheFilePath(const std::string& url)
146     {
147         std::shared_lock<std::shared_mutex> lock(cacheFilePathMutex_);
148 #if !defined(PREVIEW)
149         return cacheFilePath_ + "/" + std::to_string(std::hash<std::string> {}(url));
150 #elif defined(MAC_PLATFORM) || defined(LINUX_PLATFORM)
151         return "/tmp/" + std::to_string(std::hash<std::string> {}(url));
152 #elif defined(WINDOWS_PLATFORM)
153         char* pathvar;
154         pathvar = getenv("TEMP");
155         if (!pathvar) {
156             return std::string("C:\\Windows\\Temp") + "\\" + std::to_string(std::hash<std::string> {}(url));
157         }
158         return std::string(pathvar) + "\\" + std::to_string(std::hash<std::string> {}(url));
159 #endif
160     }
161 
SetCacheFileLimit(size_t cacheFileLimit)162     static void SetCacheFileLimit(size_t cacheFileLimit)
163     {
164         LOGI("Set file cache limit size : %{public}d", static_cast<int32_t>(cacheFileLimit));
165         cacheFileLimit_ = cacheFileLimit;
166     }
167 
SetClearCacheFileRatio(float clearRatio)168     static void SetClearCacheFileRatio(float clearRatio)
169     {
170         // clearRatio must in (0, 1].
171         if (clearRatio < 0) {
172             clearRatio = 0.1f;
173         } else if (clearRatio > 1) {
174             clearRatio = 1.0f;
175         }
176         clearCacheFileRatio_ = clearRatio;
177     }
178 
179     static bool GetFromCacheFile(const std::string& filePath);
180 
181     virtual void Clear() = 0;
182 
183     virtual RefPtr<CachedImageData> GetDataFromCacheFile(const std::string& filePath) = 0;
184 
185     static void Purge();
186 
187 protected:
188     static void ClearCacheFile(const std::vector<std::string>& removeFiles);
189 
190     template<typename T>
191     static void CacheWithCountLimitLRU(const std::string& key, const T& cacheObj, std::list<CacheNode<T>>& cacheList,
192         std::unordered_map<std::string, typename std::list<CacheNode<T>>::iterator>& cache,
193         const std::atomic<size_t>& capacity);
194 
195     template<typename T>
196     static T GetCacheObjWithCountLimitLRU(const std::string& key, std::list<CacheNode<T>>& cacheList,
197         std::unordered_map<std::string, typename std::list<CacheNode<T>>::iterator>& cache);
198 
199     static bool GetFromCacheFileInner(const std::string& filePath);
200 
201     bool ProcessImageDataCacheInner(size_t dataSize);
202 
203     mutable std::mutex imageCacheMutex_;
204     std::list<CacheNode<std::shared_ptr<CachedImage>>> cacheList_;
205     std::list<CacheNode<std::shared_ptr<NG::CachedImage>>> cacheListNG_;
206 
207     std::unordered_map<std::string, std::list<CacheNode<std::shared_ptr<CachedImage>>>::iterator> imageCache_;
208     std::unordered_map<std::string, std::list<CacheNode<std::shared_ptr<NG::CachedImage>>>::iterator> imageCacheNG_;
209 
210     std::atomic<size_t> capacity_ = 0; // by default memory cache can store 0 images.
211 
212     mutable std::mutex dataCacheListMutex_;
213     std::list<CacheImageDataNode> dataCacheList_;
214 
215     std::mutex imageDataCacheMutex_;
216     std::unordered_map<std::string, std::list<CacheImageDataNode>::iterator> imageDataCache_;
217 
218     std::atomic<size_t> dataSizeLimit_ = 0; // by default, image data before decoded cache is 0 MB.;
219     std::atomic<size_t> curDataSize_ = 0;
220 
221     std::mutex cacheImgObjListMutex_;
222     std::list<CacheNode<RefPtr<ImageObject>>> cacheImgObjList_;
223     std::mutex imgObjCacheMutex_;
224     std::unordered_map<std::string, std::list<CacheNode<RefPtr<ImageObject>>>::iterator> imgObjCache_;
225     std::atomic<size_t> imgObjCapacity_ = 2000; // imgObj is cached after clear image data.
226 
227     std::list<CacheNode<RefPtr<NG::ImageObject>>> cacheImgObjListNG_;
228     std::unordered_map<std::string, std::list<CacheNode<RefPtr<NG::ImageObject>>>::iterator> imgObjCacheNG_;
229 
230     static std::shared_mutex cacheFilePathMutex_;
231     static std::string cacheFilePath_;
232 
233     static std::atomic<size_t> cacheFileLimit_;
234 
235     static std::atomic<float> clearCacheFileRatio_;
236 
237     static std::mutex cacheFileSizeMutex_;
238     static int32_t cacheFileSize_;
239 
240     static std::mutex cacheFileInfoMutex_;
241     static std::list<FileInfo> cacheFileInfo_;
242     static bool hasSetCacheFileInfo_;
243 };
244 
245 struct PixmapCachedData : public CachedImageData {
246     DECLARE_ACE_TYPE(PixmapCachedData, CachedImageData);
247 
248 public:
PixmapCachedDataPixmapCachedData249     explicit PixmapCachedData(const RefPtr<PixelMap>& data) : pixmap_(data) {}
250     ~PixmapCachedData() override = default;
251 
GetSizePixmapCachedData252     size_t GetSize() override
253     {
254         return pixmap_ ? pixmap_->GetByteCount() : 0;
255     }
256 
GetDataPixmapCachedData257     const uint8_t* GetData() override
258     {
259         return pixmap_ ? pixmap_->GetPixels() : nullptr;
260     }
261 
262     const RefPtr<PixelMap> pixmap_;
263 };
264 
265 } // namespace OHOS::Ace
266 
267 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_IMAGE_CACHE_H
268