15ba71b47Sopenharmony_ci/*
25ba71b47Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
35ba71b47Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
45ba71b47Sopenharmony_ci * you may not use this file except in compliance with the License.
55ba71b47Sopenharmony_ci * You may obtain a copy of the License at
65ba71b47Sopenharmony_ci *
75ba71b47Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
85ba71b47Sopenharmony_ci *
95ba71b47Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
105ba71b47Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
115ba71b47Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125ba71b47Sopenharmony_ci * See the License for the specific language governing permissions and
135ba71b47Sopenharmony_ci * limitations under the License.
145ba71b47Sopenharmony_ci */
155ba71b47Sopenharmony_ci
165ba71b47Sopenharmony_ci#ifndef DYNAMIC_CACHE_H
175ba71b47Sopenharmony_ci#define DYNAMIC_CACHE_H
185ba71b47Sopenharmony_ci
195ba71b47Sopenharmony_ci#include <map>
205ba71b47Sopenharmony_ci#include <string>
215ba71b47Sopenharmony_ci#include <vector>
225ba71b47Sopenharmony_ci
235ba71b47Sopenharmony_ci#include "datetime_ex.h"
245ba71b47Sopenharmony_ci#include "iremote_object.h"
255ba71b47Sopenharmony_ci#include "parameter.h"
265ba71b47Sopenharmony_ci#include "refbase.h"
275ba71b47Sopenharmony_ci#include "sam_log.h"
285ba71b47Sopenharmony_ci#include "sysparam_errno.h"
295ba71b47Sopenharmony_ci
305ba71b47Sopenharmony_cinamespace OHOS {
315ba71b47Sopenharmony_ciusing namespace std;
325ba71b47Sopenharmony_ciclass DynamicCache : public IRemoteObject::DeathRecipient {
335ba71b47Sopenharmony_cipublic:
345ba71b47Sopenharmony_ci    void OnRemoteDied(const wptr<IRemoteObject>& remote) override
355ba71b47Sopenharmony_ci    {
365ba71b47Sopenharmony_ci        HILOGD("DynamicCache OnRemoteDied called");
375ba71b47Sopenharmony_ci        ClearCache();
385ba71b47Sopenharmony_ci    }
395ba71b47Sopenharmony_ci    sptr<IRemoteObject> QueryResult(int32_t querySaId, int32_t code)
405ba71b47Sopenharmony_ci    {
415ba71b47Sopenharmony_ci        int32_t waterLineLength = 128;
425ba71b47Sopenharmony_ci        char waterLine[128] = {0};
435ba71b47Sopenharmony_ci        string defaultValue = "default";
445ba71b47Sopenharmony_ci        GetParameter(key_.c_str(), defaultValue.c_str(), waterLine, waterLineLength);
455ba71b47Sopenharmony_ci        {
465ba71b47Sopenharmony_ci            std::lock_guard<std::mutex> autoLock(queryCacheLock_);
475ba71b47Sopenharmony_ci            if (CanUseCache(querySaId, waterLine, defaultValue)) {
485ba71b47Sopenharmony_ci                HILOGD("DynamicCache QueryResult Return Cache");
495ba71b47Sopenharmony_ci                return lastQuerySaProxy_;
505ba71b47Sopenharmony_ci            }
515ba71b47Sopenharmony_ci        }
525ba71b47Sopenharmony_ci        HILOGD("DynamicCache QueryResult Recompute");
535ba71b47Sopenharmony_ci        sptr<IRemoteObject> res = Recompute(querySaId, code);
545ba71b47Sopenharmony_ci        if (res == nullptr) {
555ba71b47Sopenharmony_ci            return nullptr;
565ba71b47Sopenharmony_ci        }
575ba71b47Sopenharmony_ci        {
585ba71b47Sopenharmony_ci            std::lock_guard<std::mutex> autoLock(queryCacheLock_);
595ba71b47Sopenharmony_ci            localPara_[key_] = waterLine;
605ba71b47Sopenharmony_ci            if (lastQuerySaProxy_ != nullptr) {
615ba71b47Sopenharmony_ci                HILOGD("DynamicCache RemoveDeathRecipient");
625ba71b47Sopenharmony_ci                lastQuerySaProxy_->RemoveDeathRecipient(this);
635ba71b47Sopenharmony_ci            }
645ba71b47Sopenharmony_ci            lastQuerySaId_ = querySaId;
655ba71b47Sopenharmony_ci            lastQuerySaProxy_ = res;
665ba71b47Sopenharmony_ci            res->AddDeathRecipient(this);
675ba71b47Sopenharmony_ci        }
685ba71b47Sopenharmony_ci        return res;
695ba71b47Sopenharmony_ci    }
705ba71b47Sopenharmony_ci
715ba71b47Sopenharmony_ci    bool CanUseCache(int32_t querySaId, char* waterLine, string defaultValue)
725ba71b47Sopenharmony_ci    {
735ba71b47Sopenharmony_ci        return localPara_.count(key_) != 0 && lastQuerySaId_ == querySaId &&
745ba71b47Sopenharmony_ci            defaultValue != string(waterLine) && string(waterLine) == localPara_[key_] &&
755ba71b47Sopenharmony_ci            lastQuerySaProxy_ != nullptr && !lastQuerySaProxy_->IsObjectDead();
765ba71b47Sopenharmony_ci    }
775ba71b47Sopenharmony_ci
785ba71b47Sopenharmony_ci    __attribute__((no_sanitize("cfi")))
795ba71b47Sopenharmony_ci    void ClearCache()
805ba71b47Sopenharmony_ci    {
815ba71b47Sopenharmony_ci        std::lock_guard<std::mutex> autoLock(queryCacheLock_);
825ba71b47Sopenharmony_ci        if (lastQuerySaProxy_ != nullptr) {
835ba71b47Sopenharmony_ci            HILOGD("DynamicCache RemoveDeathRecipient");
845ba71b47Sopenharmony_ci            lastQuerySaProxy_->RemoveDeathRecipient(this);
855ba71b47Sopenharmony_ci        }
865ba71b47Sopenharmony_ci        lastQuerySaId_ = -1;
875ba71b47Sopenharmony_ci        lastQuerySaProxy_ = nullptr;
885ba71b47Sopenharmony_ci    }
895ba71b47Sopenharmony_ci
905ba71b47Sopenharmony_ci    bool InvalidateCache()
915ba71b47Sopenharmony_ci    {
925ba71b47Sopenharmony_ci        HILOGD("DynamicCache InvalidateCache Begin");
935ba71b47Sopenharmony_ci        string tickCount = to_string(GetTickCount());
945ba71b47Sopenharmony_ci        int32_t ret = SetParameter(key_.c_str(), tickCount.c_str());
955ba71b47Sopenharmony_ci        if (ret != EC_SUCCESS) {
965ba71b47Sopenharmony_ci            HILOGE("DynamicCache InvalidateCache SetParameter error:%{public}d!", ret);
975ba71b47Sopenharmony_ci            return false;
985ba71b47Sopenharmony_ci        }
995ba71b47Sopenharmony_ci        HILOGD("DynamicCache InvalidateCache End");
1005ba71b47Sopenharmony_ci        return true;
1015ba71b47Sopenharmony_ci    }
1025ba71b47Sopenharmony_ci
1035ba71b47Sopenharmony_ci    bool SetKey(const string& key)
1045ba71b47Sopenharmony_ci    {
1055ba71b47Sopenharmony_ci        int32_t maxLength = 256;
1065ba71b47Sopenharmony_ci        if (key.size() == 0 || (int32_t)key.size() > maxLength) {
1075ba71b47Sopenharmony_ci            HILOGE("DynamicCache SetKey size error:%{public}zu!", key.size());
1085ba71b47Sopenharmony_ci            return false;
1095ba71b47Sopenharmony_ci        }
1105ba71b47Sopenharmony_ci        key_ = key;
1115ba71b47Sopenharmony_ci        return true;
1125ba71b47Sopenharmony_ci    }
1135ba71b47Sopenharmony_ci
1145ba71b47Sopenharmony_ci    virtual sptr<IRemoteObject> Recompute(int32_t querySaId, int32_t code)
1155ba71b47Sopenharmony_ci    {
1165ba71b47Sopenharmony_ci        std::lock_guard<std::mutex> autoLock(queryCacheLock_);
1175ba71b47Sopenharmony_ci        if (lastQuerySaId_ != querySaId) {
1185ba71b47Sopenharmony_ci            return nullptr;
1195ba71b47Sopenharmony_ci        }
1205ba71b47Sopenharmony_ci        return lastQuerySaProxy_;
1215ba71b47Sopenharmony_ci    }
1225ba71b47Sopenharmony_ciprivate:
1235ba71b47Sopenharmony_ci    std::mutex queryCacheLock_;
1245ba71b47Sopenharmony_ci    map<string, string> localPara_;
1255ba71b47Sopenharmony_ci    string key_;
1265ba71b47Sopenharmony_ci    int32_t lastQuerySaId_;
1275ba71b47Sopenharmony_ci    sptr<IRemoteObject> lastQuerySaProxy_;
1285ba71b47Sopenharmony_ci};
1295ba71b47Sopenharmony_ci}
1305ba71b47Sopenharmony_ci#endif /* DYNAMIC_CACHE_H */