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 
16 #include "lru_cache_disk_handler.h"
17 
18 #include <thread>
19 
20 #include "netstack_log.h"
21 
22 namespace OHOS::NetStack::Http {
LRUCacheDiskHandler(std::string fileName,size_t capacity)23 LRUCacheDiskHandler::LRUCacheDiskHandler(std::string fileName, size_t capacity)
24     : diskHandler_(std::move(fileName)),
25       capacity_(std::max<size_t>(std::min<size_t>(MAX_DISK_CACHE_SIZE, capacity), MIN_DISK_CACHE_SIZE))
26 {
27 }
28 
SetCapacity(size_t capacity)29 void LRUCacheDiskHandler::SetCapacity(size_t capacity)
30 {
31     capacity_ = std::max<size_t>(std::min<size_t>(MAX_DISK_CACHE_SIZE, capacity), MIN_DISK_CACHE_SIZE);
32     WriteCacheToJsonFile();
33 }
34 
Delete()35 void LRUCacheDiskHandler::Delete()
36 {
37     cache_.Clear();
38     diskHandler_.Delete();
39 }
40 
ReadJsonValueFromFile()41 cJSON* LRUCacheDiskHandler::ReadJsonValueFromFile()
42 {
43     std::string jsonStr = diskHandler_.Read();
44     cJSON *root = cJSON_Parse(jsonStr.c_str());
45     if (root == nullptr) {
46         NETSTACK_LOGE("parse json not success, maybe file is broken");
47         return nullptr;
48     }
49     return root;
50 }
51 
WriteJsonValueToFile(const cJSON * root)52 void LRUCacheDiskHandler::WriteJsonValueToFile(const cJSON *root)
53 {
54     char *jsonStr = cJSON_Print(root);
55     if (jsonStr == nullptr) {
56         NETSTACK_LOGE("write json failed");
57         return;
58     }
59     std::string s = jsonStr;
60     diskHandler_.Write(s);
61     free(jsonStr);
62 }
63 
WriteCacheToJsonFile()64 void LRUCacheDiskHandler::WriteCacheToJsonFile()
65 {
66     LRUCache oldCache(capacity_);
67     cJSON *readRoot = ReadJsonValueFromFile();
68     oldCache.ReadCacheFromJsonValue(readRoot);
69     cJSON_Delete(readRoot);
70     oldCache.MergeOtherCache(cache_);
71     cJSON *writeRoot = oldCache.WriteCacheToJsonValue();
72     WriteJsonValueToFile(writeRoot);
73     cJSON_Delete(writeRoot);
74     cache_.Clear();
75 }
76 
ReadCacheFromJsonFile()77 void LRUCacheDiskHandler::ReadCacheFromJsonFile()
78 {
79     cJSON *root = ReadJsonValueFromFile();
80     cache_.ReadCacheFromJsonValue(root);
81     cJSON_Delete(root);
82 }
83 
Get(const std::string & key)84 std::unordered_map<std::string, std::string> LRUCacheDiskHandler::Get(const std::string &key)
85 {
86     auto valueFromMemory = cache_.Get(key);
87     if (!valueFromMemory.empty()) {
88         return valueFromMemory;
89     }
90 
91     LRUCache diskCache(capacity_);
92     cJSON *root = ReadJsonValueFromFile();
93     diskCache.ReadCacheFromJsonValue(root);
94     cJSON_Delete(root);
95     auto valueFromDisk = diskCache.Get(key);
96     cache_.Put(key, valueFromDisk);
97     return valueFromDisk;
98 }
99 
Put(const std::string & key,const std::unordered_map<std::string,std::string> & value)100 void LRUCacheDiskHandler::Put(const std::string &key, const std::unordered_map<std::string, std::string> &value)
101 {
102     cache_.Put(key, value);
103 }
104 } // namespace OHOS::NetStack::Http
105