• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2024 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 "medialibrary_kvstore_manager.h"
17 
18 #include <atomic>
19 #include <shared_mutex>
20 
21 #include "medialibrary_errno.h"
22 #include "media_file_utils.h"
23 #include "media_log.h"
24 
25 using namespace OHOS::DistributedKv;
26 namespace OHOS::Media {
27 
InitKvStore(const KvStoreRoleType & roleType,const KvStoreValueType & valueType)28 std::shared_ptr<MediaLibraryKvStore> MediaLibraryKvStoreManager::InitKvStore(const KvStoreRoleType &roleType,
29     const KvStoreValueType &valueType)
30 {
31     std::lock_guard<std::mutex> lock(mutex_);
32     KvStoreSharedPtr ptr;
33     if (kvStoreMap_.Find(valueType, ptr)) {
34         return ptr;
35     }
36 
37     std::string baseDir = "";
38     if (roleType == KvStoreRoleType::OWNER) {
39         baseDir = KV_STORE_OWNER_DIR;
40     } else if (roleType == KvStoreRoleType::VISITOR) {
41         baseDir = KV_STORE_VISITOR_DIR;
42     } else {
43         MEDIA_ERR_LOG("invalid role type");
44         return nullptr;
45     }
46 
47     ptr = std::make_shared<MediaLibraryKvStore>();
48     int32_t status = ptr->Init(roleType, valueType, baseDir);
49     if (status != E_OK) {
50         MEDIA_ERR_LOG("init kvStore failed, status %{public}d", status);
51         return nullptr;
52     }
53     kvStoreMap_.Insert(valueType, ptr);
54     return ptr;
55 }
56 
GetKvStore(const KvStoreRoleType & roleType,const KvStoreValueType & valueType)57 std::shared_ptr<MediaLibraryKvStore> MediaLibraryKvStoreManager::GetKvStore(
58     const KvStoreRoleType &roleType, const KvStoreValueType &valueType)
59 {
60     int64_t currentTimestamp = MediaFileUtils::UTCTimeMilliSeconds();
61     kvStoreEvokedTimeStamp_.store(currentTimestamp);
62     KvStoreSharedPtr ptr;
63     CHECK_AND_RETURN_RET(!kvStoreMap_.Find(valueType, ptr), ptr);
64 
65     return InitKvStore(roleType, valueType);
66 }
67 
CloseAllKvStore()68 void MediaLibraryKvStoreManager::CloseAllKvStore()
69 {
70     std::lock_guard<std::mutex> lock(mutex_);
71     if (kvStoreMap_.IsEmpty()) {
72         return;
73     }
74 
75     kvStoreMap_.Clear();
76 }
77 
TryCloseAllKvStore()78 void MediaLibraryKvStoreManager::TryCloseAllKvStore()
79 {
80     int64_t kvIdleTime = MediaFileUtils::UTCTimeMilliSeconds() - kvStoreEvokedTimeStamp_.load();
81     if (!kvStoreMap_.IsEmpty() && kvIdleTime > static_cast<int64_t>(CLOSE_KVSTORE_TIME_INTERVAL)) {
82         std::lock_guard<std::mutex> lock(mutex_);
83         kvStoreMap_.Clear();
84     }
85 }
86 
CloseKvStore(const KvStoreValueType & valueType)87 bool MediaLibraryKvStoreManager::CloseKvStore(const KvStoreValueType &valueType)
88 {
89     std::lock_guard<std::mutex> lock(mutex_);
90     KvStoreSharedPtr ptr;
91     if (!kvStoreMap_.Find(valueType, ptr)) {
92         return false;
93     }
94 
95     if (ptr != nullptr && ptr->Close()) {
96         kvStoreMap_.Erase(valueType);
97         MEDIA_INFO_LOG("CloseKvStore success, valueType %{public}d", valueType);
98         return true;
99     }
100     return false;
101 }
102 
InitMonthAndYearKvStore(const KvStoreRoleType & roleType)103 bool MediaLibraryKvStoreManager::InitMonthAndYearKvStore(const KvStoreRoleType& roleType)
104 {
105     if (roleType != KvStoreRoleType::OWNER) {
106         return false;
107     }
108     if (GetKvStore(roleType, KvStoreValueType::MONTH_ASTC) == nullptr ||
109         GetKvStore(roleType, KvStoreValueType::YEAR_ASTC) == nullptr) {
110         return false;
111     }
112     return true;
113 }
114 
IsKvStoreValid(const KvStoreValueType & valueType)115 bool MediaLibraryKvStoreManager::IsKvStoreValid(const KvStoreValueType &valueType)
116 {
117     KvStoreSharedPtr ptr;
118     CHECK_AND_RETURN_RET(!kvStoreMap_.Find(valueType, ptr), true);
119 
120     ptr = std::make_shared<MediaLibraryKvStore>();
121     int32_t status = ptr->Init(KvStoreRoleType::OWNER, valueType, KV_STORE_OWNER_DIR);
122     CHECK_AND_RETURN_RET_LOG(status != static_cast<int32_t>(Status::DATA_CORRUPTED), false,
123         "KvStore is invalid and needs to be deleted, status %{public}d, type %{public}d",
124         status, valueType);
125 
126     if (status == E_OK && ptr != nullptr) {
127         ptr->Close();
128     }
129     return true;
130 }
131 
RebuildInvalidKvStore(const KvStoreValueType & valueType)132 int32_t MediaLibraryKvStoreManager::RebuildInvalidKvStore(const KvStoreValueType &valueType)
133 {
134     std::lock_guard<std::mutex> lock(mutex_);
135     kvStoreMap_.Erase(valueType);
136     KvStoreSharedPtr ptr = std::make_shared<MediaLibraryKvStore>();
137     return ptr->RebuildKvStore(valueType, KV_STORE_OWNER_DIR);
138 }
139 
GetSingleKvStore(const KvStoreRoleType & roleType,const std::string & storeId,const std::string & baseDir)140 std::shared_ptr<MediaLibraryKvStore> MediaLibraryKvStoreManager::GetSingleKvStore(
141     const KvStoreRoleType &roleType, const std::string &storeId, const std::string &baseDir)
142 {
143     KvStoreSharedPtr ptr = std::make_shared<MediaLibraryKvStore>();
144     int32_t status = ptr->InitSingleKvstore(roleType, storeId, baseDir);
145     CHECK_AND_RETURN_RET_LOG(status == E_OK, nullptr, "Init kvStore failed, status %{public}d", status);
146     return ptr;
147 }
148 
CloneKvStore(const std::string & oldKvStoreId,const std::string & oldBaseDir,const std::string & newKvStoreId,const std::string & newBaseDir)149 int32_t MediaLibraryKvStoreManager::CloneKvStore(const std::string &oldKvStoreId, const std::string &oldBaseDir,
150     const std::string &newKvStoreId, const std::string &newBaseDir)
151 {
152     KvStoreSharedPtr oldKvStore = std::make_shared<MediaLibraryKvStore>();
153     int32_t status = oldKvStore->InitSingleKvstore(KvStoreRoleType::OWNER, oldKvStoreId, oldBaseDir);
154     CHECK_AND_RETURN_RET_LOG(status == E_OK, status, "Init old kvStore failed, status %{public}d", status);
155 
156     KvStoreSharedPtr newKvStore = std::make_shared<MediaLibraryKvStore>();
157     status = newKvStore->InitSingleKvstore(KvStoreRoleType::OWNER, newKvStoreId, newBaseDir);
158     CHECK_AND_RETURN_RET_LOG(status == E_OK, status, "Init new kvStore failed, status %{public}d", status);
159 
160     status = oldKvStore->PutAllValueToNewKvStore(newKvStore);
161     CHECK_AND_RETURN_RET_LOG(status == E_OK, status, "Clone kvstore failed, status %{public}d", status);
162     return E_OK;
163 }
164 } // namespace OHOS::Media