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