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 FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_IMAGE_FILE_CACHE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_IMAGE_FILE_CACHE_H
18 #include <list>
19 #include <mutex>
20 #include <shared_mutex>
21 #include <unordered_map>
22 #include <utility>
23 #include <vector>
24 
25 #include "base/utils/singleton.h"
26 #include "core/components_ng/image_provider/image_data.h"
27 
28 namespace OHOS::Ace {
29 struct FileInfo {
FileInfoFileInfo30     FileInfo(std::string name, size_t size, time_t time, size_t cnt)
31         : fileName(std::move(name)), fileSize(size), accessTime(time), accessCount(cnt) {}
32 
33     // file information will be sort by access time.
34     bool operator<(const FileInfo& otherFile) const
35     {
36         return accessTime > otherFile.accessTime;
37     }
38     std::string fileName;
39     size_t fileSize;
40     time_t accessTime;
41     size_t accessCount;
42 };
43 
44 class ImageFileCache : public Singleton<ImageFileCache> {
45     DECLARE_SINGLETON(ImageFileCache);
46     ACE_DISALLOW_MOVE(ImageFileCache);
47 public:
48     void SetImageCacheFilePath(const std::string& cacheFilePath);
49     std::string GetImageCacheFilePath();
50     std::string GetImageCacheFilePath(const std::string& url);
51     std::string GetImageCacheKey(const std::string& fileName);
52 
53     void SetCacheFileLimit(size_t cacheFileLimit);
54     void SetClearCacheFileRatio(float clearRatio);
55 
56     std::string GetCacheFilePath(const std::string& url);
57 
58     RefPtr<NG::ImageData> GetDataFromCacheFile(const std::string& url, const std::string& suffix);
59 
60     void SetCacheFileInfo();
61     void WriteCacheFile(
62         const std::string& url, const void* data, size_t size, const std::string& suffix = std::string());
63     void EraseCacheFile(const std::string& url);
64     void ClearCacheFile(const std::vector<std::string>& removeFiles);
65     std::string ConstructCacheFilePath(const std::string& fileName);
66     void DumpCacheInfo();
67 private:
68     void SaveCacheInner(const std::string& cacheKey, const std::string& suffix, size_t cacheSize,
69         std::vector<std::string>& removeVector);
70     std::string GetCacheFilePathInner(const std::string& url, const std::string& suffix);
71     void ConvertToAstcAndWriteToFile(const std::string& fileCacheKey, const std::string& filePath,
72         const std::string& url);
73     bool WriteFile(const std::string& url, const void* const data, size_t size,
74         const std::string& fileCacheKey, const std::string& suffix);
75 
76     std::shared_mutex cacheFilePathMutex_;
77     std::string cacheFilePath_;
78 
79     std::atomic<size_t> fileLimit_ = 100 * 1024 * 1024; // the capacity is 100MB
80 
81     std::atomic<float> clearCacheFileRatio_ = 0.5f; // default clear ratio is 0.5
82 
83     std::mutex cacheFileSizeMutex_;
84     size_t cacheFileSize_ = 0;
85 
86     std::mutex cacheFileInfoMutex_;
87     // lru
88     std::list<FileInfo> cacheFileInfo_;
89     std::unordered_map<std::string, std::list<FileInfo>::iterator> fileNameToFileInfoPos_;
90 
91     bool hasSetCacheFileInfo_ = false;
92 };
93 } // namespace OHOS::Ace
94 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_IMAGE_IMAGE_FILE_CACHE_H