1fc223305Sopenharmony_ci/*
2fc223305Sopenharmony_ci * Copyright (c) 2023 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#ifndef PREFERENCES_FRAMEWORKS_POOL_H
17fc223305Sopenharmony_ci#define PREFERENCES_FRAMEWORKS_POOL_H
18fc223305Sopenharmony_ci#include <functional>
19fc223305Sopenharmony_ci#include <mutex>
20fc223305Sopenharmony_cinamespace OHOS {
21fc223305Sopenharmony_cinamespace NativePreferences {
22fc223305Sopenharmony_ci
23fc223305Sopenharmony_citemplate<typename T>
24fc223305Sopenharmony_ciclass Pool {
25fc223305Sopenharmony_cipublic:
26fc223305Sopenharmony_ci    Pool(uint32_t capability, uint32_t min) : capability_(capability), min_(min) {}
27fc223305Sopenharmony_ci
28fc223305Sopenharmony_ci    std::shared_ptr<T> Get(bool isForce = false)
29fc223305Sopenharmony_ci    {
30fc223305Sopenharmony_ci        std::unique_lock<decltype(mutex_)> lock(mutex_);
31fc223305Sopenharmony_ci        if (idle_ == nullptr) {
32fc223305Sopenharmony_ci            if (!isForce && current_ >= capability_) {
33fc223305Sopenharmony_ci                return nullptr;
34fc223305Sopenharmony_ci            }
35fc223305Sopenharmony_ci            auto cur = new Node();
36fc223305Sopenharmony_ci            idle_ = cur;
37fc223305Sopenharmony_ci            current_++;
38fc223305Sopenharmony_ci        }
39fc223305Sopenharmony_ci        Node *cur = idle_;
40fc223305Sopenharmony_ci        idle_ = idle_->next;
41fc223305Sopenharmony_ci        if (idle_ != nullptr) {
42fc223305Sopenharmony_ci            idle_->prev = nullptr;
43fc223305Sopenharmony_ci        }
44fc223305Sopenharmony_ci        cur->next = busy_;
45fc223305Sopenharmony_ci        if (busy_ != nullptr) {
46fc223305Sopenharmony_ci            cur->prev = busy_->prev;
47fc223305Sopenharmony_ci            busy_->prev = cur;
48fc223305Sopenharmony_ci        }
49fc223305Sopenharmony_ci        busy_ = cur;
50fc223305Sopenharmony_ci        return cur->data;
51fc223305Sopenharmony_ci    };
52fc223305Sopenharmony_ci
53fc223305Sopenharmony_ci    int32_t Release(std::shared_ptr<T> data, bool force = false)
54fc223305Sopenharmony_ci    {
55fc223305Sopenharmony_ci        std::unique_lock<decltype(mutex_)> lock(mutex_);
56fc223305Sopenharmony_ci        Node *cur = idle_;
57fc223305Sopenharmony_ci        if (!force && current_ <= min_) {
58fc223305Sopenharmony_ci            return false;
59fc223305Sopenharmony_ci        }
60fc223305Sopenharmony_ci        while (cur != nullptr) {
61fc223305Sopenharmony_ci            if (cur->data == data) {
62fc223305Sopenharmony_ci                if (cur->next != nullptr) {
63fc223305Sopenharmony_ci                    cur->next->prev = cur->prev;
64fc223305Sopenharmony_ci                }
65fc223305Sopenharmony_ci                if (cur->prev != nullptr) {
66fc223305Sopenharmony_ci                    cur->prev->next = cur->next;
67fc223305Sopenharmony_ci                }
68fc223305Sopenharmony_ci                if (idle_ == cur) {
69fc223305Sopenharmony_ci                    idle_ = cur->next;
70fc223305Sopenharmony_ci                }
71fc223305Sopenharmony_ci                current_--;
72fc223305Sopenharmony_ci                delete cur;
73fc223305Sopenharmony_ci                return true;
74fc223305Sopenharmony_ci            } else {
75fc223305Sopenharmony_ci                cur = cur->next;
76fc223305Sopenharmony_ci                continue;
77fc223305Sopenharmony_ci            }
78fc223305Sopenharmony_ci        }
79fc223305Sopenharmony_ci        return false;
80fc223305Sopenharmony_ci    }
81fc223305Sopenharmony_ci
82fc223305Sopenharmony_ci    void Idle(std::shared_ptr<T> data)
83fc223305Sopenharmony_ci    {
84fc223305Sopenharmony_ci        std::unique_lock<decltype(mutex_)> lock(mutex_);
85fc223305Sopenharmony_ci        Node *cur = busy_;
86fc223305Sopenharmony_ci        while (cur != nullptr && cur->data != data) {
87fc223305Sopenharmony_ci            cur = cur->next;
88fc223305Sopenharmony_ci        }
89fc223305Sopenharmony_ci        if (cur == nullptr) {
90fc223305Sopenharmony_ci            return;
91fc223305Sopenharmony_ci        }
92fc223305Sopenharmony_ci        if (cur == busy_) {
93fc223305Sopenharmony_ci            busy_ = busy_->next;
94fc223305Sopenharmony_ci        }
95fc223305Sopenharmony_ci        if (cur->next != nullptr) {
96fc223305Sopenharmony_ci            cur->next->prev = cur->prev;
97fc223305Sopenharmony_ci        }
98fc223305Sopenharmony_ci        if (cur->prev != nullptr) {
99fc223305Sopenharmony_ci            cur->prev->next = cur->next;
100fc223305Sopenharmony_ci        }
101fc223305Sopenharmony_ci        cur->prev = nullptr;
102fc223305Sopenharmony_ci        cur->next = idle_;
103fc223305Sopenharmony_ci        if (idle_ != nullptr) {
104fc223305Sopenharmony_ci            idle_->prev = cur;
105fc223305Sopenharmony_ci        }
106fc223305Sopenharmony_ci        idle_ = cur;
107fc223305Sopenharmony_ci    }
108fc223305Sopenharmony_ci
109fc223305Sopenharmony_ci    int32_t Clean(std::function<void(std::shared_ptr<T>)> close) noexcept
110fc223305Sopenharmony_ci    {
111fc223305Sopenharmony_ci        auto temp = min_;
112fc223305Sopenharmony_ci        min_ = 0;
113fc223305Sopenharmony_ci        while (busy_ != nullptr) {
114fc223305Sopenharmony_ci            close(busy_->data);
115fc223305Sopenharmony_ci        }
116fc223305Sopenharmony_ci        while (idle_ != nullptr) {
117fc223305Sopenharmony_ci            close(idle_->data);
118fc223305Sopenharmony_ci        }
119fc223305Sopenharmony_ci        min_ = temp;
120fc223305Sopenharmony_ci        return true;
121fc223305Sopenharmony_ci    }
122fc223305Sopenharmony_ci
123fc223305Sopenharmony_ciprivate:
124fc223305Sopenharmony_ci    struct Node {
125fc223305Sopenharmony_ci        Node *prev = nullptr;
126fc223305Sopenharmony_ci        Node *next = nullptr;
127fc223305Sopenharmony_ci        std::shared_ptr<T> data = std::make_shared<T>();
128fc223305Sopenharmony_ci    };
129fc223305Sopenharmony_ci
130fc223305Sopenharmony_ci    uint32_t capability_;
131fc223305Sopenharmony_ci    uint32_t min_;
132fc223305Sopenharmony_ci    uint32_t current_ = 0;
133fc223305Sopenharmony_ci    Node *idle_ = nullptr;
134fc223305Sopenharmony_ci    Node *busy_ = nullptr;
135fc223305Sopenharmony_ci    std::mutex mutex_;
136fc223305Sopenharmony_ci};
137fc223305Sopenharmony_ci} // namespace NativePreferences
138fc223305Sopenharmony_ci} // namespace OHOS
139fc223305Sopenharmony_ci
140fc223305Sopenharmony_ci#endif // PREFERENCES_FRAMEWORKS_POOL_H
141