1 /* 2 * Copyright (c) 2024 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 META_API_CONTAINER_FIND_CACHE_H 17 #define META_API_CONTAINER_FIND_CACHE_H 18 19 #include <meta/api/event_handler.h> 20 #include <meta/api/internal/object_api.h> 21 #include <meta/api/threading/mutex.h> 22 #include <meta/interface/intf_container.h> 23 24 META_BEGIN_NAMESPACE() 25 26 /** 27 * @brief The FindCache class is a helper class for caching the results of a FindAny/FindAll operation on an IContainer. 28 */ 29 template<class Type> 30 class FindCache { 31 public: 32 FindCache() = default; 33 ~FindCache() = default; 34 /** 35 * @brief Sets the target for FindCache. 36 * @param container Target container. 37 * @param options Find options for IContainer::Find operation. 38 */ SetTarget(const META_NS::IContainer::ConstPtr& container, const META_NS::IContainer::FindOptions& options)39 void SetTarget(const META_NS::IContainer::ConstPtr& container, const META_NS::IContainer::FindOptions& options) 40 { 41 CORE_NS::UniqueLock lock(mutex_); 42 ResetTarget(); 43 if (container) { 44 container_ = container; 45 options_ = options; 46 const auto cb = MakeCallback<IOnChildChanged>([this](const ChildChangedInfo&) { Invalidate(); }); 47 addedHandler_.Subscribe(container->OnAdded(), cb); 48 removedHandler_.Subscribe(container->OnRemoved(), cb); 49 } 50 } 51 /** 52 * @brief Returns true if a valid target has been set. 53 */ 54 bool HasTarget() const noexcept 55 { 56 return !container_.expired(); 57 } 58 /** 59 * @brief Calls IContainer::FindAny, caches and returns the result. Any subsequent FindAny calls return 60 * the cached result unless changes have been made to the container. 61 */ FindAny() const62 typename Type::Ptr FindAny() const 63 { 64 CORE_NS::UniqueLock lock(mutex_); 65 if (const auto container = container_.lock()) { 66 if (!cached_.IsSet(CachedResultTypeBitsValue::FIND_ANY_CACHED)) { 67 resultAny_ = container->template FindAny<Type>(options_); 68 cached_.Set(CachedResultTypeBitsValue::FIND_ANY_CACHED); 69 } 70 return resultAny_; 71 } 72 return {}; 73 } 74 /** 75 * @brief Calls IContainer::FindAll, caches and returns the result. Any subsequent FindAll calls return 76 * the cached result unless changes have been made to the container. 77 */ FindAll() const78 BASE_NS::vector<typename Type::Ptr> FindAll() const 79 { 80 CORE_NS::UniqueLock lock(mutex_); 81 if (const auto container = container_.lock()) { 82 if (!cached_.IsSet(CachedResultTypeBitsValue::FIND_ALL_CACHED)) { 83 resultAll_ = PtrArrayCast<Type>(container->FindAll(options_)); 84 cached_.Set(CachedResultTypeBitsValue::FIND_ALL_CACHED); 85 } 86 return resultAll_; 87 } 88 return {}; 89 } 90 /** 91 * @brief Invalidates the cached query results. 92 */ Invalidate()93 void Invalidate() 94 { 95 CORE_NS::UniqueLock lock(mutex_); 96 ClearResults(); 97 } 98 /** 99 * @brief Resets the cache (results and target). 100 */ Reset()101 void Reset() 102 { 103 CORE_NS::UniqueLock lock(mutex_); 104 ResetTarget(); 105 } 106 107 private: ResetTarget()108 void ResetTarget() 109 { 110 ClearResults(); 111 container_.reset(); 112 options_ = {}; 113 } ClearResults()114 void ClearResults() 115 { 116 resultAny_.reset(); 117 resultAll_.clear(); 118 cached_.Clear(); 119 } 120 enum class CachedResultTypeBitsValue : uint16_t { 121 FIND_ANY_CACHED = 1, 122 FIND_ALL_CACHED = 2, 123 }; 124 125 mutable CORE_NS::Mutex mutex_; 126 mutable EnumBitField<CachedResultTypeBitsValue> cached_; 127 mutable typename Type::Ptr resultAny_; 128 mutable BASE_NS::vector<typename Type::Ptr> resultAll_; 129 META_NS::IContainer::ConstWeakPtr container_; 130 META_NS::IContainer::FindOptions options_; 131 EventHandler addedHandler_; 132 EventHandler removedHandler_; 133 }; 134 135 META_END_NAMESPACE() 136 137 #endif // META_API_CONTAINER_FIND_CACHE_H 138