115053c2dSopenharmony_ci/*
215053c2dSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
315053c2dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
415053c2dSopenharmony_ci * you may not use this file except in compliance with the License.
515053c2dSopenharmony_ci * You may obtain a copy of the License at
615053c2dSopenharmony_ci *
715053c2dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
815053c2dSopenharmony_ci *
915053c2dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1015053c2dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1115053c2dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1215053c2dSopenharmony_ci * See the License for the specific language governing permissions and
1315053c2dSopenharmony_ci * limitations under the License.
1415053c2dSopenharmony_ci */
1515053c2dSopenharmony_ci
1615053c2dSopenharmony_ci#ifndef OHOS_DISTRIBUTED_DATA_KV_STORE_FRAMEWORKS_COMMON_POOL_H
1715053c2dSopenharmony_ci#define OHOS_DISTRIBUTED_DATA_KV_STORE_FRAMEWORKS_COMMON_POOL_H
1815053c2dSopenharmony_ci#include <functional>
1915053c2dSopenharmony_ci#include <mutex>
2015053c2dSopenharmony_cinamespace OHOS {
2115053c2dSopenharmony_citemplate<typename T>
2215053c2dSopenharmony_ciclass Pool {
2315053c2dSopenharmony_cipublic:
2415053c2dSopenharmony_ci    Pool(uint32_t capability, uint32_t min) : capability_(capability), min_(min) {}
2515053c2dSopenharmony_ci
2615053c2dSopenharmony_ci    std::shared_ptr<T> Get(bool isForce = false)
2715053c2dSopenharmony_ci    {
2815053c2dSopenharmony_ci        std::unique_lock<decltype(mutex_)> lock(mutex_);
2915053c2dSopenharmony_ci        if (idle_ == nullptr) {
3015053c2dSopenharmony_ci            if (!isForce && current_ >= capability_) {
3115053c2dSopenharmony_ci                return nullptr;
3215053c2dSopenharmony_ci            }
3315053c2dSopenharmony_ci            auto cur = new Node();
3415053c2dSopenharmony_ci            idle_ = cur;
3515053c2dSopenharmony_ci            current_++;
3615053c2dSopenharmony_ci        }
3715053c2dSopenharmony_ci        Node *cur = idle_;
3815053c2dSopenharmony_ci        idle_ = idle_->next;
3915053c2dSopenharmony_ci        if (idle_ != nullptr) {
4015053c2dSopenharmony_ci            idle_->prev = nullptr;
4115053c2dSopenharmony_ci        }
4215053c2dSopenharmony_ci        cur->next = busy_;
4315053c2dSopenharmony_ci        if (busy_ != nullptr) {
4415053c2dSopenharmony_ci            cur->prev = busy_->prev;
4515053c2dSopenharmony_ci            busy_->prev = cur;
4615053c2dSopenharmony_ci        }
4715053c2dSopenharmony_ci        busy_ = cur;
4815053c2dSopenharmony_ci        return cur->data;
4915053c2dSopenharmony_ci    };
5015053c2dSopenharmony_ci
5115053c2dSopenharmony_ci    int32_t Release(std::shared_ptr<T> data, bool force = false)
5215053c2dSopenharmony_ci    {
5315053c2dSopenharmony_ci        std::unique_lock<decltype(mutex_)> lock(mutex_);
5415053c2dSopenharmony_ci        Node *cur = idle_;
5515053c2dSopenharmony_ci        if (!force && current_ <= min_) {
5615053c2dSopenharmony_ci            return false;
5715053c2dSopenharmony_ci        }
5815053c2dSopenharmony_ci        while (cur != nullptr) {
5915053c2dSopenharmony_ci            if (cur->data == data) {
6015053c2dSopenharmony_ci                if (cur->next != nullptr) {
6115053c2dSopenharmony_ci                    cur->next->prev = cur->prev;
6215053c2dSopenharmony_ci                }
6315053c2dSopenharmony_ci                if (cur->prev != nullptr) {
6415053c2dSopenharmony_ci                    cur->prev->next = cur->next;
6515053c2dSopenharmony_ci                }
6615053c2dSopenharmony_ci                if (idle_ == cur) {
6715053c2dSopenharmony_ci                    idle_ = cur->next;
6815053c2dSopenharmony_ci                }
6915053c2dSopenharmony_ci                current_--;
7015053c2dSopenharmony_ci                delete cur;
7115053c2dSopenharmony_ci                return true;
7215053c2dSopenharmony_ci            } else {
7315053c2dSopenharmony_ci                cur = cur->next;
7415053c2dSopenharmony_ci                continue;
7515053c2dSopenharmony_ci            }
7615053c2dSopenharmony_ci        }
7715053c2dSopenharmony_ci        return false;
7815053c2dSopenharmony_ci    }
7915053c2dSopenharmony_ci
8015053c2dSopenharmony_ci    void Idle(std::shared_ptr<T> data)
8115053c2dSopenharmony_ci    {
8215053c2dSopenharmony_ci        std::unique_lock<decltype(mutex_)> lock(mutex_);
8315053c2dSopenharmony_ci        Node *cur = busy_;
8415053c2dSopenharmony_ci        while (cur != nullptr && cur->data != data) {
8515053c2dSopenharmony_ci            cur = cur->next;
8615053c2dSopenharmony_ci        }
8715053c2dSopenharmony_ci        if (cur == nullptr) {
8815053c2dSopenharmony_ci            return;
8915053c2dSopenharmony_ci        }
9015053c2dSopenharmony_ci        if (cur == busy_) {
9115053c2dSopenharmony_ci            busy_ = busy_->next;
9215053c2dSopenharmony_ci        }
9315053c2dSopenharmony_ci        if (cur->next != nullptr) {
9415053c2dSopenharmony_ci            cur->next->prev = cur->prev;
9515053c2dSopenharmony_ci        }
9615053c2dSopenharmony_ci        if (cur->prev != nullptr) {
9715053c2dSopenharmony_ci            cur->prev->next = cur->next;
9815053c2dSopenharmony_ci        }
9915053c2dSopenharmony_ci        cur->prev = nullptr;
10015053c2dSopenharmony_ci        cur->next = idle_;
10115053c2dSopenharmony_ci        if (idle_ != nullptr) {
10215053c2dSopenharmony_ci            idle_->prev = cur;
10315053c2dSopenharmony_ci        }
10415053c2dSopenharmony_ci        idle_ = cur;
10515053c2dSopenharmony_ci    }
10615053c2dSopenharmony_ci
10715053c2dSopenharmony_ci    int32_t Clean(std::function<void(std::shared_ptr<T>)> close) noexcept
10815053c2dSopenharmony_ci    {
10915053c2dSopenharmony_ci        auto temp = min_;
11015053c2dSopenharmony_ci        min_ = 0;
11115053c2dSopenharmony_ci        while (busy_ != nullptr) {
11215053c2dSopenharmony_ci            close(busy_->data);
11315053c2dSopenharmony_ci        }
11415053c2dSopenharmony_ci        while (idle_ != nullptr) {
11515053c2dSopenharmony_ci            close(idle_->data);
11615053c2dSopenharmony_ci        }
11715053c2dSopenharmony_ci        min_ = temp;
11815053c2dSopenharmony_ci        return true;
11915053c2dSopenharmony_ci    }
12015053c2dSopenharmony_ci
12115053c2dSopenharmony_ciprivate:
12215053c2dSopenharmony_ci    struct Node {
12315053c2dSopenharmony_ci        Node *prev = nullptr;
12415053c2dSopenharmony_ci        Node *next = nullptr;
12515053c2dSopenharmony_ci        std::shared_ptr<T> data = std::make_shared<T>();
12615053c2dSopenharmony_ci    };
12715053c2dSopenharmony_ci
12815053c2dSopenharmony_ci    uint32_t capability_;
12915053c2dSopenharmony_ci    uint32_t min_;
13015053c2dSopenharmony_ci    uint32_t current_ = 0;
13115053c2dSopenharmony_ci    Node *idle_ = nullptr;
13215053c2dSopenharmony_ci    Node *busy_ = nullptr;
13315053c2dSopenharmony_ci    std::mutex mutex_;
13415053c2dSopenharmony_ci};
13515053c2dSopenharmony_ci} // namespace OHOS
13615053c2dSopenharmony_ci
13715053c2dSopenharmony_ci#endif // OHOS_DISTRIBUTED_DATA_KV_STORE_FRAMEWORKS_COMMON_POOL_H
138