• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
META_BEGIN_NAMESPACE()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      */
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             changedHandler_.Subscribe(container->OnContainerChanged(), cb);
48         }
49     }
50     /**
51      * @brief Returns true if a valid target has been set.
52      */
53     bool HasTarget() const noexcept
54     {
55         return !container_.expired();
56     }
57     /**
58      * @brief Calls IContainer::FindAny, caches and returns the result. Any subsequent FindAny calls return
59      *        the cached result unless changes have been made to the container.
60      */
61     typename Type::Ptr FindAny() const
62     {
63         CORE_NS::UniqueLock lock(mutex_);
64         if (const auto container = container_.lock()) {
65             if (!cached_.IsSet(CachedResultTypeBitsValue::FIND_ANY_CACHED)) {
66                 resultAny_ = container->template FindAny<Type>(options_);
67                 cached_.Set(CachedResultTypeBitsValue::FIND_ANY_CACHED);
68             }
69             return resultAny_;
70         }
71         return {};
72     }
73     /**
74      * @brief Calls IContainer::FindAll, caches and returns the result. Any subsequent FindAll calls return
75      *        the cached result unless changes have been made to the container.
76      */
77     BASE_NS::vector<typename Type::Ptr> FindAll() const
78     {
79         CORE_NS::UniqueLock lock(mutex_);
80         if (const auto container = container_.lock()) {
81             if (!cached_.IsSet(CachedResultTypeBitsValue::FIND_ALL_CACHED)) {
82                 resultAll_ = PtrArrayCast<Type>(container->FindAll(options_));
83                 cached_.Set(CachedResultTypeBitsValue::FIND_ALL_CACHED);
84             }
85             return resultAll_;
86         }
87         return {};
88     }
89     /**
90      * @brief Invalidates the cached query results.
91      */
92     void Invalidate()
93     {
94         CORE_NS::UniqueLock lock(mutex_);
95         ClearResults();
96     }
97     /**
98      * @brief Resets the cache (results and target).
99      */
100     void Reset()
101     {
102         CORE_NS::UniqueLock lock(mutex_);
103         ResetTarget();
104     }
105 
106 private:
107     void ResetTarget()
108     {
109         ClearResults();
110         container_.reset();
111         options_ = {};
112     }
113     void ClearResults()
114     {
115         resultAny_.reset();
116         resultAll_.clear();
117         cached_.Clear();
118     }
119     enum class CachedResultTypeBitsValue : uint16_t {
120         FIND_ANY_CACHED = 1,
121         FIND_ALL_CACHED = 2,
122     };
123 
124     mutable CORE_NS::Mutex mutex_;
125     mutable EnumBitField<CachedResultTypeBitsValue> cached_;
126     mutable typename Type::Ptr resultAny_;
127     mutable BASE_NS::vector<typename Type::Ptr> resultAll_;
128     META_NS::IContainer::ConstWeakPtr container_;
129     META_NS::IContainer::FindOptions options_;
130     EventHandler changedHandler_;
131 };
132 
133 META_END_NAMESPACE()
134 
135 #endif // META_API_CONTAINER_FIND_CACHE_H
136