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 HOLDER_MANAGER_H_ 17 #define HOLDER_MANAGER_H_ 18 19 #include <atomic> 20 #include <cstdint> 21 #include <map> 22 #include <memory> 23 #include <mutex> 24 #include <string> 25 #include <securec.h> 26 #include <type_traits> 27 28 namespace OHOS { 29 namespace FileAccessFwk { 30 template<typename Type> 31 class HolderManager { 32 public: 33 static constexpr int CODE_CAN_NOT_FIND = 0; HolderManager()34 HolderManager() {} 35 ~HolderManager()36 ~HolderManager() 37 { 38 std::lock_guard<std::mutex> guard(holderMutex_); 39 holder_.clear(); 40 HILOG_INFO("~HolderManager holder size: %{public}zu", holder_.size()); 41 } 42 save(Type content)43 uint32_t save(Type content) 44 { 45 uint32_t id; 46 do { 47 id = genId(); 48 } while (exist(id)); 49 std::lock_guard<std::mutex> guard(holderMutex_); 50 holder_.insert(std::pair<uint32_t, Type>(id, content)); 51 HILOG_INFO("save id:%{public}d holder size: %{public}zu", id, holder_.size()); 52 return id; 53 } 54 get(uint32_t id)55 Type get(uint32_t id) 56 { 57 std::lock_guard<std::mutex> guard(holderMutex_); 58 auto iter = holder_.find(id); 59 if (iter != holder_.end()) { 60 return iter->second; 61 } 62 return Type(); 63 } 64 pop(uint32_t id)65 Type pop(uint32_t id) 66 { 67 std::lock_guard<std::mutex> guard(holderMutex_); 68 auto iter = holder_.find(id); 69 if (iter != holder_.end()) { 70 auto res = iter->second; 71 holder_.erase(id); 72 HILOG_INFO("pop id: %{public}d find holder size: %{public}zu", id, holder_.size()); 73 return res; 74 } 75 HILOG_INFO("pop id: %{public}d not find holder size: %{public}zu", id, holder_.size()); 76 return Type(); 77 } 78 release(uint32_t id)79 void release(uint32_t id) 80 { 81 std::lock_guard<std::mutex> guard(holderMutex_); 82 if (holder_.count(id)) { 83 HILOG_INFO("release id: %{public}d find holder size: %{public}zu", id, holder_.size()); 84 holder_.erase(id); 85 } else { 86 HILOG_INFO("release id: %{public}d not find holder size: %{public}zu", id, holder_.size()); 87 } 88 } 89 exist(uint32_t id)90 bool exist(uint32_t id) 91 { 92 std::lock_guard<std::mutex> guard(holderMutex_); 93 return holder_.count(id); 94 } 95 getId(std::function<bool (const Type &)> func)96 uint32_t getId(std::function<bool(const Type &)> func) 97 { 98 auto haveIter = find_if(holder_.begin(), holder_.end(), 99 [func](const std::pair<uint32_t, Type> type) { 100 return func(type.second); 101 }); 102 if (haveIter == holder_.end()) { 103 return CODE_CAN_NOT_FIND; 104 } 105 return haveIter->first; 106 } 107 getAll(std::vector<Type> & contexts)108 void getAll(std::vector<Type> &contexts) 109 { 110 std::lock_guard<std::mutex> guard(holderMutex_); 111 for (auto &iter : holder_) { 112 contexts.push_back(iter.second); 113 } 114 } 115 isEmpty()116 bool isEmpty() 117 { 118 std::lock_guard<std::mutex> guard(holderMutex_); 119 return holder_.empty(); 120 } 121 122 private: 123 // key is automatic growth number 124 std::map<uint32_t, Type> holder_; 125 std::mutex holderMutex_; 126 std::atomic<uint32_t> gId_ = 1; genId()127 uint32_t genId() 128 { 129 return gId_++; 130 } 131 }; 132 } // namespace FileAccessFwk 133 } // namespace OHOS 134 #endif // FRAMEWORKS_INNERKITSIMPL_UTILS_INCLUDE_IMAGE_HOLDER_MANAGER_H_