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 #define LOG_TAG "StoreCache"
16 #include "store_cache.h"
17 #include <chrono>
18 #include <string>
19
20 #include "log_print.h"
21 #include "runtime_store.h"
22 #include "unified_meta.h"
23 #include "account/account_delegate.h"
24
25 namespace OHOS {
26 namespace UDMF {
GetInstance()27 StoreCache &StoreCache::GetInstance()
28 {
29 static StoreCache instance;
30 return instance;
31 }
32
GetStore(std::string intention)33 std::shared_ptr<Store> StoreCache::GetStore(std::string intention)
34 {
35 std::shared_ptr<Store> store;
36 int foregroundUserId = 0;
37 bool ret = DistributedKv::AccountDelegate::GetInstance()->QueryForegroundUserId(foregroundUserId);
38 if (!ret) {
39 ZLOGE("QueryForegroundUserId failed.");
40 return nullptr;
41 }
42 std::string key = intention;
43 key.append(std::to_string(foregroundUserId));
44
45 stores_.Compute(key, [&store, intention](const auto &key, std::shared_ptr<Store> &storePtr) -> bool {
46 if (storePtr != nullptr) {
47 store = storePtr;
48 return true;
49 }
50
51 if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)
52 || intention == UD_INTENTION_MAP.at(UD_INTENTION_DATA_HUB)) {
53 storePtr = std::make_shared<RuntimeStore>(intention);
54 if (!storePtr->Init()) {
55 ZLOGE("Init runtime store failed.");
56 return false;
57 }
58 store = storePtr;
59 return true;
60 }
61 return false;
62 });
63
64 std::unique_lock<std::mutex> lock(taskMutex_);
65 if (taskId_ == ExecutorPool::INVALID_TASK_ID && executorPool_ != nullptr) {
66 taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this));
67 }
68 return store;
69 }
70
GarbageCollect()71 void StoreCache::GarbageCollect()
72 {
73 auto current = std::chrono::steady_clock::now();
74 stores_.EraseIf([¤t](auto &key, std::shared_ptr<Store> &storePtr) {
75 if (*storePtr < current) {
76 ZLOGI("GarbageCollect, stores:%{public}s time limit, will be close.", key.c_str());
77 return true;
78 }
79 return false;
80 });
81 std::unique_lock<std::mutex> lock(taskMutex_);
82 if (!stores_.Empty() && executorPool_ != nullptr) {
83 ZLOGD("GarbageCollect, stores size:%{public}zu", stores_.Size());
84 taskId_ = executorPool_->Schedule(std::chrono::minutes(INTERVAL), std::bind(&StoreCache::GarbageCollect, this));
85 } else {
86 taskId_ = ExecutorPool::INVALID_TASK_ID;
87 }
88 }
89
SetThreadPool(std::shared_ptr<ExecutorPool> executors)90 void StoreCache::SetThreadPool(std::shared_ptr<ExecutorPool> executors)
91 {
92 executorPool_ = executors;
93 }
94 } // namespace UDMF
95 } // namespace OHOS
96