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([&current](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