1fc223305Sopenharmony_ci/* 2fc223305Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3fc223305Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fc223305Sopenharmony_ci * you may not use this file except in compliance with the License. 5fc223305Sopenharmony_ci * You may obtain a copy of the License at 6fc223305Sopenharmony_ci * 7fc223305Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fc223305Sopenharmony_ci * 9fc223305Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fc223305Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fc223305Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fc223305Sopenharmony_ci * See the License for the specific language governing permissions and 13fc223305Sopenharmony_ci * limitations under the License. 14fc223305Sopenharmony_ci */ 15fc223305Sopenharmony_ci 16fc223305Sopenharmony_ci#include "preferences_enhance_impl.h" 17fc223305Sopenharmony_ci 18fc223305Sopenharmony_ci#include <cinttypes> 19fc223305Sopenharmony_ci#include <climits> 20fc223305Sopenharmony_ci#include <cstdint> 21fc223305Sopenharmony_ci#include <cstdlib> 22fc223305Sopenharmony_ci#include <functional> 23fc223305Sopenharmony_ci#include <sstream> 24fc223305Sopenharmony_ci#include <thread> 25fc223305Sopenharmony_ci 26fc223305Sopenharmony_ci#include "executor_pool.h" 27fc223305Sopenharmony_ci#include "preferences_file_operation.h" 28fc223305Sopenharmony_ci#include "log_print.h" 29fc223305Sopenharmony_ci#include "preferences_observer_stub.h" 30fc223305Sopenharmony_ci#include "preferences_value.h" 31fc223305Sopenharmony_ci#include "preferences_value_parcel.h" 32fc223305Sopenharmony_ci 33fc223305Sopenharmony_cinamespace OHOS { 34fc223305Sopenharmony_cinamespace NativePreferences { 35fc223305Sopenharmony_ci 36fc223305Sopenharmony_ciconstexpr int32_t CACHED_THRESHOLDS = 512 * 1024; // we will cached big obj(len >= 512k) 37fc223305Sopenharmony_ci 38fc223305Sopenharmony_ciPreferencesEnhanceImpl::PreferencesEnhanceImpl(const Options &options): PreferencesBase(options) 39fc223305Sopenharmony_ci{ 40fc223305Sopenharmony_ci} 41fc223305Sopenharmony_ci 42fc223305Sopenharmony_ciPreferencesEnhanceImpl::~PreferencesEnhanceImpl() 43fc223305Sopenharmony_ci{ 44fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 45fc223305Sopenharmony_ci db_ = nullptr; 46fc223305Sopenharmony_ci} 47fc223305Sopenharmony_ci 48fc223305Sopenharmony_ciint PreferencesEnhanceImpl::Init() 49fc223305Sopenharmony_ci{ 50fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 51fc223305Sopenharmony_ci db_ = std::make_shared<PreferencesDb>(); 52fc223305Sopenharmony_ci cachedDataVersion_ = 0; 53fc223305Sopenharmony_ci int errCode = db_->Init(options_.filePath, options_.bundleName); 54fc223305Sopenharmony_ci if (errCode != E_OK) { 55fc223305Sopenharmony_ci db_ = nullptr; 56fc223305Sopenharmony_ci } 57fc223305Sopenharmony_ci return errCode; 58fc223305Sopenharmony_ci} 59fc223305Sopenharmony_ci 60fc223305Sopenharmony_ciPreferencesValue PreferencesEnhanceImpl::Get(const std::string &key, const PreferencesValue &defValue) 61fc223305Sopenharmony_ci{ 62fc223305Sopenharmony_ci if (CheckKey(key) != E_OK) { 63fc223305Sopenharmony_ci return defValue; 64fc223305Sopenharmony_ci } 65fc223305Sopenharmony_ci // write lock here, get not support concurrence 66fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 67fc223305Sopenharmony_ci if (db_ == nullptr) { 68fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:Get failed, db has been closed."); 69fc223305Sopenharmony_ci return defValue; 70fc223305Sopenharmony_ci } 71fc223305Sopenharmony_ci 72fc223305Sopenharmony_ci int64_t kernelDataVersion = 0; 73fc223305Sopenharmony_ci if (db_->GetKernelDataVersion(kernelDataVersion) != E_OK) { 74fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:Get failed, get kernel data version failed."); 75fc223305Sopenharmony_ci return defValue; 76fc223305Sopenharmony_ci } 77fc223305Sopenharmony_ci if (kernelDataVersion == cachedDataVersion_) { 78fc223305Sopenharmony_ci auto it = largeCachedData_.find(key); 79fc223305Sopenharmony_ci if (it != largeCachedData_.end()) { 80fc223305Sopenharmony_ci return it->second; 81fc223305Sopenharmony_ci } 82fc223305Sopenharmony_ci } 83fc223305Sopenharmony_ci 84fc223305Sopenharmony_ci std::vector<uint8_t> oriKey(key.begin(), key.end()); 85fc223305Sopenharmony_ci std::vector<uint8_t> oriValue; 86fc223305Sopenharmony_ci int errCode = db_->Get(oriKey, oriValue); 87fc223305Sopenharmony_ci if (errCode != E_OK) { 88fc223305Sopenharmony_ci LOG_ERROR("get key failed, errCode=%{public}d", errCode); 89fc223305Sopenharmony_ci return defValue; 90fc223305Sopenharmony_ci } 91fc223305Sopenharmony_ci auto item = PreferencesValueParcel::UnmarshallingPreferenceValue(oriValue); 92fc223305Sopenharmony_ci if (item.first != E_OK) { 93fc223305Sopenharmony_ci LOG_ERROR("get key failed, errCode=%{public}d", item.first); 94fc223305Sopenharmony_ci return defValue; 95fc223305Sopenharmony_ci } 96fc223305Sopenharmony_ci if (oriValue.size() >= CACHED_THRESHOLDS) { 97fc223305Sopenharmony_ci largeCachedData_.insert_or_assign(key, item.second); 98fc223305Sopenharmony_ci cachedDataVersion_ = kernelDataVersion; 99fc223305Sopenharmony_ci } 100fc223305Sopenharmony_ci return item.second; 101fc223305Sopenharmony_ci} 102fc223305Sopenharmony_ci 103fc223305Sopenharmony_cibool PreferencesEnhanceImpl::HasKey(const std::string &key) 104fc223305Sopenharmony_ci{ 105fc223305Sopenharmony_ci if (CheckKey(key) != E_OK) { 106fc223305Sopenharmony_ci return false; 107fc223305Sopenharmony_ci } 108fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 109fc223305Sopenharmony_ci if (db_ == nullptr) { 110fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:HasKey failed, db has been closed."); 111fc223305Sopenharmony_ci return false; 112fc223305Sopenharmony_ci } 113fc223305Sopenharmony_ci 114fc223305Sopenharmony_ci int64_t kernelDataVersion = 0; 115fc223305Sopenharmony_ci if (db_->GetKernelDataVersion(kernelDataVersion) != E_OK) { 116fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:HasKey failed, get kernel data version failed."); 117fc223305Sopenharmony_ci return false; 118fc223305Sopenharmony_ci } 119fc223305Sopenharmony_ci if (kernelDataVersion == cachedDataVersion_) { 120fc223305Sopenharmony_ci auto it = largeCachedData_.find(key); 121fc223305Sopenharmony_ci if (it != largeCachedData_.end()) { 122fc223305Sopenharmony_ci return true; 123fc223305Sopenharmony_ci } 124fc223305Sopenharmony_ci } 125fc223305Sopenharmony_ci 126fc223305Sopenharmony_ci std::vector<uint8_t> oriKey(key.begin(), key.end()); 127fc223305Sopenharmony_ci std::vector<uint8_t> oriValue; 128fc223305Sopenharmony_ci int errCode = db_->Get(oriKey, oriValue); 129fc223305Sopenharmony_ci if (errCode != E_OK) { 130fc223305Sopenharmony_ci LOG_ERROR("get key failed, errCode=%{public}d", errCode); 131fc223305Sopenharmony_ci return false; 132fc223305Sopenharmony_ci } 133fc223305Sopenharmony_ci if (oriValue.size() >= CACHED_THRESHOLDS) { 134fc223305Sopenharmony_ci auto item = PreferencesValueParcel::UnmarshallingPreferenceValue(oriValue); 135fc223305Sopenharmony_ci if (item.first != E_OK) { 136fc223305Sopenharmony_ci LOG_WARN("haskey unmarshall failed, haskey return true, errCode=%{public}d", item.first); 137fc223305Sopenharmony_ci return true; 138fc223305Sopenharmony_ci } 139fc223305Sopenharmony_ci largeCachedData_.insert_or_assign(key, item.second); 140fc223305Sopenharmony_ci cachedDataVersion_ = kernelDataVersion; 141fc223305Sopenharmony_ci } 142fc223305Sopenharmony_ci return true; 143fc223305Sopenharmony_ci} 144fc223305Sopenharmony_ci 145fc223305Sopenharmony_ciint PreferencesEnhanceImpl::Put(const std::string &key, const PreferencesValue &value) 146fc223305Sopenharmony_ci{ 147fc223305Sopenharmony_ci int errCode = CheckKey(key); 148fc223305Sopenharmony_ci if (errCode != E_OK) { 149fc223305Sopenharmony_ci return errCode; 150fc223305Sopenharmony_ci } 151fc223305Sopenharmony_ci errCode = CheckValue(value); 152fc223305Sopenharmony_ci if (errCode != E_OK) { 153fc223305Sopenharmony_ci return errCode; 154fc223305Sopenharmony_ci } 155fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 156fc223305Sopenharmony_ci if (db_ == nullptr) { 157fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:Put failed, db has been closed."); 158fc223305Sopenharmony_ci return E_ERROR; 159fc223305Sopenharmony_ci } 160fc223305Sopenharmony_ci 161fc223305Sopenharmony_ci std::vector<uint8_t> oriValue; 162fc223305Sopenharmony_ci uint32_t oriValueLen = PreferencesValueParcel::CalSize(value); 163fc223305Sopenharmony_ci oriValue.resize(oriValueLen); 164fc223305Sopenharmony_ci errCode = PreferencesValueParcel::MarshallingPreferenceValue(value, oriValue); 165fc223305Sopenharmony_ci if (errCode != E_OK) { 166fc223305Sopenharmony_ci LOG_ERROR("marshalling value failed, errCode=%{public}d", errCode); 167fc223305Sopenharmony_ci return errCode; 168fc223305Sopenharmony_ci } 169fc223305Sopenharmony_ci std::vector<uint8_t> oriKey(key.begin(), key.end()); 170fc223305Sopenharmony_ci errCode = db_->Put(oriKey, oriValue); 171fc223305Sopenharmony_ci if (errCode != E_OK) { 172fc223305Sopenharmony_ci LOG_ERROR("put data failed, errCode=%{public}d", errCode); 173fc223305Sopenharmony_ci return errCode; 174fc223305Sopenharmony_ci } 175fc223305Sopenharmony_ci 176fc223305Sopenharmony_ci // update cached and version 177fc223305Sopenharmony_ci if (oriValueLen >= CACHED_THRESHOLDS) { 178fc223305Sopenharmony_ci largeCachedData_.insert_or_assign(key, value); 179fc223305Sopenharmony_ci cachedDataVersion_ = cachedDataVersion_ == INT64_MAX ? 0 : cachedDataVersion_ + 1; 180fc223305Sopenharmony_ci } else { 181fc223305Sopenharmony_ci auto pos = largeCachedData_.find(key); 182fc223305Sopenharmony_ci if (pos != largeCachedData_.end()) { 183fc223305Sopenharmony_ci largeCachedData_.erase(pos); 184fc223305Sopenharmony_ci } 185fc223305Sopenharmony_ci } 186fc223305Sopenharmony_ci 187fc223305Sopenharmony_ci ExecutorPool::Task task = [pref = shared_from_this(), key, value] { 188fc223305Sopenharmony_ci PreferencesEnhanceImpl::NotifyPreferencesObserver(pref, key, value); 189fc223305Sopenharmony_ci }; 190fc223305Sopenharmony_ci executorPool_.Execute(std::move(task)); 191fc223305Sopenharmony_ci return E_OK; 192fc223305Sopenharmony_ci} 193fc223305Sopenharmony_ci 194fc223305Sopenharmony_ciint PreferencesEnhanceImpl::Delete(const std::string &key) 195fc223305Sopenharmony_ci{ 196fc223305Sopenharmony_ci int errCode = CheckKey(key); 197fc223305Sopenharmony_ci if (errCode != E_OK) { 198fc223305Sopenharmony_ci return errCode; 199fc223305Sopenharmony_ci } 200fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 201fc223305Sopenharmony_ci if (db_ == nullptr) { 202fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:Delete failed, db has been closed."); 203fc223305Sopenharmony_ci return E_ERROR; 204fc223305Sopenharmony_ci } 205fc223305Sopenharmony_ci 206fc223305Sopenharmony_ci std::vector<uint8_t> oriKey(key.begin(), key.end()); 207fc223305Sopenharmony_ci errCode = db_->Delete(oriKey); 208fc223305Sopenharmony_ci if (errCode != E_OK) { 209fc223305Sopenharmony_ci LOG_ERROR("delete data failed, errCode=%{public}d", errCode); 210fc223305Sopenharmony_ci return errCode; 211fc223305Sopenharmony_ci } 212fc223305Sopenharmony_ci 213fc223305Sopenharmony_ci // update cached and version 214fc223305Sopenharmony_ci auto it = largeCachedData_.find(key); 215fc223305Sopenharmony_ci if (it != largeCachedData_.end()) { 216fc223305Sopenharmony_ci largeCachedData_.erase(it); 217fc223305Sopenharmony_ci cachedDataVersion_ = cachedDataVersion_ == INT64_MAX ? 0 : cachedDataVersion_ + 1; 218fc223305Sopenharmony_ci } 219fc223305Sopenharmony_ci 220fc223305Sopenharmony_ci PreferencesValue value; 221fc223305Sopenharmony_ci ExecutorPool::Task task = [pref = shared_from_this(), key, value] { 222fc223305Sopenharmony_ci PreferencesEnhanceImpl::NotifyPreferencesObserver(pref, key, value); 223fc223305Sopenharmony_ci }; 224fc223305Sopenharmony_ci executorPool_.Execute(std::move(task)); 225fc223305Sopenharmony_ci return E_OK; 226fc223305Sopenharmony_ci} 227fc223305Sopenharmony_ci 228fc223305Sopenharmony_cistd::pair<int, std::map<std::string, PreferencesValue>> PreferencesEnhanceImpl::GetAllInner() 229fc223305Sopenharmony_ci{ 230fc223305Sopenharmony_ci std::map<std::string, PreferencesValue> map; 231fc223305Sopenharmony_ci if (db_ == nullptr) { 232fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:GetAll failed, db has been closed."); 233fc223305Sopenharmony_ci return std::make_pair(E_ALREADY_CLOSED, map); 234fc223305Sopenharmony_ci } 235fc223305Sopenharmony_ci 236fc223305Sopenharmony_ci int64_t kernelDataVersion = 0; 237fc223305Sopenharmony_ci if (db_->GetKernelDataVersion(kernelDataVersion) != E_OK) { 238fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:GetAll failed, get kernel data version failed."); 239fc223305Sopenharmony_ci return std::make_pair(E_ERROR, map); 240fc223305Sopenharmony_ci } 241fc223305Sopenharmony_ci 242fc223305Sopenharmony_ci std::map<std::string, PreferencesValue> result; 243fc223305Sopenharmony_ci std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> data; 244fc223305Sopenharmony_ci int errCode = db_->GetAll(data); 245fc223305Sopenharmony_ci if (errCode != E_OK) { 246fc223305Sopenharmony_ci LOG_ERROR("get all failed, errCode=%{public}d", errCode); 247fc223305Sopenharmony_ci return std::make_pair(errCode, map); 248fc223305Sopenharmony_ci } 249fc223305Sopenharmony_ci for (auto it = data.begin(); it != data.end(); it++) { 250fc223305Sopenharmony_ci std::string key(it->first.begin(), it->first.end()); 251fc223305Sopenharmony_ci auto item = PreferencesValueParcel::UnmarshallingPreferenceValue(it->second); 252fc223305Sopenharmony_ci result.insert({key, item.second}); 253fc223305Sopenharmony_ci if (item.first != E_OK) { 254fc223305Sopenharmony_ci LOG_ERROR("get key failed, errCode=%{public}d", errCode); 255fc223305Sopenharmony_ci return std::make_pair(item.first, map); 256fc223305Sopenharmony_ci } 257fc223305Sopenharmony_ci if (it->second.size() >= CACHED_THRESHOLDS) { 258fc223305Sopenharmony_ci largeCachedData_.insert_or_assign(key, item.second); 259fc223305Sopenharmony_ci } 260fc223305Sopenharmony_ci } 261fc223305Sopenharmony_ci cachedDataVersion_ = kernelDataVersion; 262fc223305Sopenharmony_ci return std::make_pair(E_OK, result); 263fc223305Sopenharmony_ci} 264fc223305Sopenharmony_ci 265fc223305Sopenharmony_cistd::map<std::string, PreferencesValue> PreferencesEnhanceImpl::GetAll() 266fc223305Sopenharmony_ci{ 267fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 268fc223305Sopenharmony_ci std::pair<int, std::map<std::string, PreferencesValue>> res = GetAllInner(); 269fc223305Sopenharmony_ci return res.second; 270fc223305Sopenharmony_ci} 271fc223305Sopenharmony_ci 272fc223305Sopenharmony_civoid PreferencesEnhanceImpl::NotifyPreferencesObserver(std::shared_ptr<PreferencesEnhanceImpl> pref, 273fc223305Sopenharmony_ci const std::string &key, const PreferencesValue &value) 274fc223305Sopenharmony_ci{ 275fc223305Sopenharmony_ci std::shared_lock<std::shared_mutex> readLock(pref->obseverMetux_); 276fc223305Sopenharmony_ci LOG_DEBUG("notify observer size:%{public}zu", pref->dataObserversMap_.size()); 277fc223305Sopenharmony_ci for (const auto &[weakPrt, keys] : pref->dataObserversMap_) { 278fc223305Sopenharmony_ci auto itKey = keys.find(key); 279fc223305Sopenharmony_ci if (itKey == keys.end()) { 280fc223305Sopenharmony_ci continue; 281fc223305Sopenharmony_ci } 282fc223305Sopenharmony_ci std::map<std::string, PreferencesValue> records = {{key, value}}; 283fc223305Sopenharmony_ci if (std::shared_ptr<PreferencesObserver> sharedPtr = weakPrt.lock()) { 284fc223305Sopenharmony_ci LOG_DEBUG("dataChange observer call, resultSize:%{public}zu", records.size()); 285fc223305Sopenharmony_ci sharedPtr->OnChange(records); 286fc223305Sopenharmony_ci } 287fc223305Sopenharmony_ci } 288fc223305Sopenharmony_ci auto dataObsMgrClient = DataObsMgrClient::GetInstance(); 289fc223305Sopenharmony_ci for (auto it = pref->localObservers_.begin(); it != pref->localObservers_.end(); ++it) { 290fc223305Sopenharmony_ci std::weak_ptr<PreferencesObserver> weakPreferencesObserver = *it; 291fc223305Sopenharmony_ci if (std::shared_ptr<PreferencesObserver> sharedPreferencesObserver = weakPreferencesObserver.lock()) { 292fc223305Sopenharmony_ci sharedPreferencesObserver->OnChange(key); 293fc223305Sopenharmony_ci } 294fc223305Sopenharmony_ci } 295fc223305Sopenharmony_ci if (dataObsMgrClient != nullptr) { 296fc223305Sopenharmony_ci dataObsMgrClient->NotifyChange(pref->MakeUri(key)); 297fc223305Sopenharmony_ci } 298fc223305Sopenharmony_ci} 299fc223305Sopenharmony_ci 300fc223305Sopenharmony_civoid PreferencesEnhanceImpl::NotifyPreferencesObserverBatchKeys(std::shared_ptr<PreferencesEnhanceImpl> pref, 301fc223305Sopenharmony_ci const std::map<std::string, PreferencesValue> &data) 302fc223305Sopenharmony_ci{ 303fc223305Sopenharmony_ci for (const auto &[key, value] : data) { 304fc223305Sopenharmony_ci NotifyPreferencesObserver(pref, key, value); 305fc223305Sopenharmony_ci } 306fc223305Sopenharmony_ci} 307fc223305Sopenharmony_ci 308fc223305Sopenharmony_ciint PreferencesEnhanceImpl::Clear() 309fc223305Sopenharmony_ci{ 310fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 311fc223305Sopenharmony_ci LOG_INFO("Clear called, file: %{public}s", ExtractFileName(options_.filePath).c_str()); 312fc223305Sopenharmony_ci if (db_ == nullptr) { 313fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:Clear failed, db has been closed."); 314fc223305Sopenharmony_ci return E_ERROR; 315fc223305Sopenharmony_ci } 316fc223305Sopenharmony_ci 317fc223305Sopenharmony_ci std::pair<int, std::map<std::string, PreferencesValue>> res = GetAllInner(); 318fc223305Sopenharmony_ci if (res.first != E_OK) { 319fc223305Sopenharmony_ci LOG_ERROR("get all failed when clear, errCode=%{public}d", res.first); 320fc223305Sopenharmony_ci return res.first; 321fc223305Sopenharmony_ci } 322fc223305Sopenharmony_ci 323fc223305Sopenharmony_ci std::map<std::string, PreferencesValue> allData = res.second; 324fc223305Sopenharmony_ci 325fc223305Sopenharmony_ci int errCode = db_->DropCollection(); 326fc223305Sopenharmony_ci if (errCode != E_OK) { 327fc223305Sopenharmony_ci LOG_ERROR("drop collection failed when clear, errCode=%{public}d", errCode); 328fc223305Sopenharmony_ci return errCode; 329fc223305Sopenharmony_ci } 330fc223305Sopenharmony_ci 331fc223305Sopenharmony_ci if (!allData.empty()) { 332fc223305Sopenharmony_ci ExecutorPool::Task task = [pref = shared_from_this(), allData] { 333fc223305Sopenharmony_ci PreferencesEnhanceImpl::NotifyPreferencesObserverBatchKeys(pref, allData); 334fc223305Sopenharmony_ci }; 335fc223305Sopenharmony_ci executorPool_.Execute(std::move(task)); 336fc223305Sopenharmony_ci } 337fc223305Sopenharmony_ci 338fc223305Sopenharmony_ci errCode = db_->CreateCollection(); 339fc223305Sopenharmony_ci if (errCode != E_OK) { 340fc223305Sopenharmony_ci LOG_ERROR("create collection failed when clear, errCode=%{public}d", errCode); 341fc223305Sopenharmony_ci return errCode; 342fc223305Sopenharmony_ci } 343fc223305Sopenharmony_ci largeCachedData_.clear(); 344fc223305Sopenharmony_ci cachedDataVersion_ = cachedDataVersion_ == INT64_MAX ? 0 : cachedDataVersion_ + 1; 345fc223305Sopenharmony_ci return E_OK; 346fc223305Sopenharmony_ci} 347fc223305Sopenharmony_ci 348fc223305Sopenharmony_ciint PreferencesEnhanceImpl::CloseDb() 349fc223305Sopenharmony_ci{ 350fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 351fc223305Sopenharmony_ci if (db_ == nullptr) { 352fc223305Sopenharmony_ci LOG_WARN("PreferencesEnhanceImpl:CloseDb failed, db has been closed, no need to close again."); 353fc223305Sopenharmony_ci return E_OK; 354fc223305Sopenharmony_ci } 355fc223305Sopenharmony_ci int errCode = db_->CloseDb(); 356fc223305Sopenharmony_ci if (errCode != E_OK) { 357fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:CloseDb failed."); 358fc223305Sopenharmony_ci return errCode; 359fc223305Sopenharmony_ci } 360fc223305Sopenharmony_ci largeCachedData_.clear(); 361fc223305Sopenharmony_ci db_ = nullptr; 362fc223305Sopenharmony_ci return E_OK; 363fc223305Sopenharmony_ci} 364fc223305Sopenharmony_ci 365fc223305Sopenharmony_cistd::pair<int, PreferencesValue> PreferencesEnhanceImpl::GetValue(const std::string &key, 366fc223305Sopenharmony_ci const PreferencesValue &defValue) 367fc223305Sopenharmony_ci{ 368fc223305Sopenharmony_ci int errCode = CheckKey(key); 369fc223305Sopenharmony_ci if (errCode != E_OK) { 370fc223305Sopenharmony_ci return std::make_pair(errCode, defValue); 371fc223305Sopenharmony_ci } 372fc223305Sopenharmony_ci // write lock here, get not support concurrence 373fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 374fc223305Sopenharmony_ci if (db_ == nullptr) { 375fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:Get failed, db has been closed."); 376fc223305Sopenharmony_ci return std::make_pair(E_ALREADY_CLOSED, defValue); 377fc223305Sopenharmony_ci } 378fc223305Sopenharmony_ci 379fc223305Sopenharmony_ci int64_t kernelDataVersion = 0; 380fc223305Sopenharmony_ci if (db_->GetKernelDataVersion(kernelDataVersion) != E_OK) { 381fc223305Sopenharmony_ci LOG_ERROR("PreferencesEnhanceImpl:Get failed, get kernel data version failed."); 382fc223305Sopenharmony_ci return std::make_pair(E_ERROR, defValue); 383fc223305Sopenharmony_ci } 384fc223305Sopenharmony_ci if (kernelDataVersion == cachedDataVersion_) { 385fc223305Sopenharmony_ci auto it = largeCachedData_.find(key); 386fc223305Sopenharmony_ci if (it != largeCachedData_.end()) { 387fc223305Sopenharmony_ci return std::make_pair(E_OK, it->second); 388fc223305Sopenharmony_ci } 389fc223305Sopenharmony_ci } 390fc223305Sopenharmony_ci 391fc223305Sopenharmony_ci std::vector<uint8_t> oriKey(key.begin(), key.end()); 392fc223305Sopenharmony_ci std::vector<uint8_t> oriValue; 393fc223305Sopenharmony_ci errCode = db_->Get(oriKey, oriValue); 394fc223305Sopenharmony_ci if (errCode != E_OK) { 395fc223305Sopenharmony_ci LOG_ERROR("get key failed, errCode=%{public}d", errCode); 396fc223305Sopenharmony_ci return std::make_pair(errCode, defValue); 397fc223305Sopenharmony_ci } 398fc223305Sopenharmony_ci auto item = PreferencesValueParcel::UnmarshallingPreferenceValue(oriValue); 399fc223305Sopenharmony_ci if (item.first != E_OK) { 400fc223305Sopenharmony_ci LOG_ERROR("get key failed, errCode=%{public}d", item.first); 401fc223305Sopenharmony_ci return std::make_pair(item.first, defValue); 402fc223305Sopenharmony_ci } 403fc223305Sopenharmony_ci if (oriValue.size() >= CACHED_THRESHOLDS) { 404fc223305Sopenharmony_ci largeCachedData_.insert_or_assign(key, item.second); 405fc223305Sopenharmony_ci cachedDataVersion_ = kernelDataVersion; 406fc223305Sopenharmony_ci } 407fc223305Sopenharmony_ci return std::make_pair(E_OK, item.second); 408fc223305Sopenharmony_ci} 409fc223305Sopenharmony_ci 410fc223305Sopenharmony_cistd::pair<int, std::map<std::string, PreferencesValue>> PreferencesEnhanceImpl::GetAllData() 411fc223305Sopenharmony_ci{ 412fc223305Sopenharmony_ci std::unique_lock<std::shared_mutex> writeLock(dbMutex_); 413fc223305Sopenharmony_ci return GetAllInner(); 414fc223305Sopenharmony_ci} 415fc223305Sopenharmony_ci} // End of namespace NativePreferences 416fc223305Sopenharmony_ci} // End of namespace OHOS 417