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