HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pageCacheStorage.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_EXEC_EF_PAGE_CACHE_STORAGE_H
8 #define PXR_EXEC_EF_PAGE_CACHE_STORAGE_H
9 
10 ///\file
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/ef/api.h"
15 #include "pxr/exec/ef/pageCache.h"
17 
18 #include "pxr/exec/vdf/lruCache.h"
19 #include "pxr/exec/vdf/request.h"
20 #include "pxr/exec/vdf/types.h"
21 
22 #include <tbb/concurrent_vector.h>
23 
24 #include <atomic>
25 #include <functional>
26 #include <memory>
27 #include <vector>
28 
30 
31 class EfLeafNodeCache;
33 class VdfMask;
34 class VdfMaskedOutput;
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 ///
38 /// \class EfPageCacheStorage
39 ///
40 /// \brief Manages a page cache and provides methods for invalidation of
41 /// cached values.
42 ///
44 {
45  // The executor needs direct access to the page cache
46  template <template <typename> class E, typename D>
48 
49  // The cache commit request needs direct access to the page cache
51 
52  // Predicate type used for invalidation. The predicate returns
53  // \c true if the page indexed by the specified key value shall
54  // receive invalidation.
55  using _CacheIteratorPredicateFunction =
56  std::function<bool (const VdfVector &)>;
57 
58 public:
59  /// Destructor.
60  ///
61  EF_API
63 
64  /// Constructor helper.
65  ///
66  /// Use this to construct heap allocated instances of this class, with the
67  /// given \p leafNodeCache.
68  ///
69  template < typename T >
70  static EfPageCacheStorage *New(
71  const VdfMaskedOutput &keyMaskedOutput,
72  EfLeafNodeCache *leafNodeCache);
73 
74  /// Returns the amount of memory currently used for cache storage, in bytes.
75  ///
76  EF_API
77  static size_t GetNumBytesUsed();
78 
79  /// Returns the upper cache storage memory limit, in bytes.
80  ///
81  EF_API
82  static size_t GetNumBytesLimit();
83 
84  /// Returns \c true, if the upper memory limit has been reached, and the
85  /// object is no longer allowed to allocate additional storage to cache
86  /// new values.
87  ///
88  EF_API
89  static bool HasReachedMemoryLimit();
90 
91  /// Sets the upper memory limit, denoting how much memory this object is
92  /// allowed to allocate.
93  ///
94  EF_API
95  static void SetMemoryUsageLimit(size_t bytes);
96 
97  /// Returns \c true if the storage is enabled, i.e. output values can be
98  /// committed and retrieved from the cache.
99  ///
100  EF_API
101  bool IsEnabled() const;
102 
103  /// Enables / disables the storage.
104  ///
105  EF_API
106  void SetEnabled(bool enable);
107 
108  /// Given any request, returns another \p request containing the outputs,
109  /// which are dependent on the key output, and thus can be committed to the
110  /// page cache.
111  ///
112  EF_API
113  const VdfRequest &GetCacheableRequest(const VdfRequest &request) const;
114 
115  /// Returns the set of keys that have been cached in the pages selected
116  /// by the \p predicate, as determined by the set of outputs contained in
117  /// the \p request.
118  /// Returns \c false if the \p request does not contain any cacheable
119  /// outputs.
120  ///
121  EF_API
122  bool GetCachedKeys(
123  const _CacheIteratorPredicateFunction &predicate,
124  const VdfRequest &request,
125  std::vector<const VdfVector *> *cachedKeys) const;
126 
127  /// Invalidate the page cache by clearing the entire cache on the pages
128  /// determined by the invalidation \p predicate.
129  ///
130  EF_API
131  void Invalidate(
132  const _CacheIteratorPredicateFunction &predicate);
133 
134  /// Invalidate the page cache by clearing the output values dependent on
135  /// the \p invalidationRequest, on the pages determined by the invalidation
136  /// \p predicate.
137  ///
138  EF_API
139  void Invalidate(
140  const _CacheIteratorPredicateFunction &predicate,
141  const VdfMaskedOutputVector &invalidationRequest);
142 
143  /// Clear the entire cache on all pages.
144  ///
145  EF_API
146  void Clear();
147 
148  /// Clears the output values associated with all the given \p nodes in the
149  /// provided \p network.
150  ///
151  EF_API
152  void ClearNodes(
153  const VdfNetwork &network,
154  const tbb::concurrent_vector<VdfIndex> &nodes);
155 
156  /// Resizes the internal structures of the page cache to be able to
157  /// accommodate output values for the provided \p network.
158  ///
159  /// \note
160  /// It's not thread-safe to Resize() while the page cache storage is
161  /// concurrently being accessed.
162  ///
163  EF_API
164  void Resize(const VdfNetwork &network);
165 
166  /// Call this to notify the page cache storage of nodes that have been
167  /// deleted from the network.
168  ///
169  EF_API
170  void WillDeleteNode(const VdfNode &node);
171 
172 private:
173  // Constructor
174  EF_API
176  const VdfMaskedOutput &keyMaskedOutput,
177  EfLeafNodeCache *leafNodeCache,
178  Ef_PageCache *newPageCache);
179 
180  // Returns \c true of the given \p output is a key output.
181  EF_API
182  bool _IsKeyOutput(
183  const VdfOutput &output,
184  const VdfMask &mask) const;
185 
186  // Returns a pointer to an existing, or newly created cache at the
187  // page indexed by \p key.
188  EF_API
189  Ef_OutputValueCache *_GetOrCreateCache(const VdfVector &key);
190 
191  // Returns a set of all outputs dependent on the specified request.
192  EF_API
193  const VdfOutputToMaskMap &_FindDependencies(
194  const VdfMaskedOutputVector &request) const;
195 
196  // Commits data to an output value cache, returning the size of the
197  // committed data, in bytes.
198  EF_API
199  size_t _Commit(
200  const VdfExecutorInterface &executor,
201  const VdfRequest &request,
203 
204  // Commits data for a single output to an output value cache, returning the
205  // size of the committed data, in bytes.
206  EF_API
207  size_t _Commit(
208  const VdfMaskedOutput &maskedOutput,
209  const VdfVector &value,
211 
212 private:
213  // The key masked output.
214  VdfMaskedOutput _keyMaskedOutput;
215 
216  // The leaf node cache.
217  EfLeafNodeCache *_leafNodeCache;
218 
219  // Pointer to the page cache managed by this class.
220  std::unique_ptr<Ef_PageCache> _pageCache;
221 
222  // An entry in the cacheableRequests cache. The entry becomes invalid on
223  // changes to the leaf node cache, so we store the leaf node cache version
224  // along with the cached request.
225  struct _CacheableRequestEntry {
226  _CacheableRequestEntry() : version(0) {}
227  size_t version;
228  VdfRequest request;
229  };
230 
231  // An LRU cache with cacheable requests.
232  using _CacheableRequests =
234  mutable _CacheableRequests _cacheableRequests;
235 
236  // Flags nodes that have had at least one output value stored in at
237  // least one page. Once added, node references will not be removed
238  // until the node is being deleted from the network. This serves as
239  // an acceleration structure, which limits the set of nodes that could
240  // possibly have output values stored in the page cache.
241  std::unique_ptr<std::atomic<bool>[]> _nodeRefs;
242  size_t _numNodeRefs;
243 
244  // The number of bytes currently used.
245  static std::atomic<size_t> _numBytesUsed;
246 
247  // The upper memory limit in bytes.
248  static std::atomic<size_t> _numBytesLimit;
249 
250  // Is this storage enabled?
251  bool _enabled;
252 
253 };
254 
255 template < typename T >
258  const VdfMaskedOutput &keyMaskedOutput,
259  EfLeafNodeCache *leafNodeCache)
260 {
261  return new EfPageCacheStorage(
262  keyMaskedOutput, leafNodeCache, Ef_PageCache::New<T>());
263 }
264 
266 
267 #endif
EF_API bool GetCachedKeys(const _CacheIteratorPredicateFunction &predicate, const VdfRequest &request, std::vector< const VdfVector * > *cachedKeys) const
EF_API void Clear()
Manages a page cache and provides methods for invalidation of cached values.
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
GLsizei const GLfloat * value
Definition: glcorearb.h:824
EF_API void SetEnabled(bool enable)
Definition: node.h:52
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
An output-to-value storage for caching. The class provides accessor types for thread-safe, as well as unprotected access.
static EF_API size_t GetNumBytesLimit()
Executes a VdfNetwork to compute a requested set of values. Caches the computed data in a EfPageCache...
EF_API const VdfRequest & GetCacheableRequest(const VdfRequest &request) const
This object signifies an intent to commit data to a page cache. It ensures that the page exists and t...
Organizes output-to-value caches into logical groups, called pages. Pages are keyed off of VdfVector ...
Definition: pageCache.h:28
GLint GLuint mask
Definition: glcorearb.h:124
static EF_API bool HasReachedMemoryLimit()
EF_API void WillDeleteNode(const VdfNode &node)
static EfPageCacheStorage * New(const VdfMaskedOutput &keyMaskedOutput, EfLeafNodeCache *leafNodeCache)
std::unordered_map< const VdfOutput *, VdfMask, TfHash > VdfOutputToMaskMap
A map from output pointer to mask.
Definition: types.h:104
Class to hold on to an externally owned output and a mask.
Definition: maskedOutput.h:31
GT_API const UT_StringHolder version
static EF_API size_t GetNumBytesUsed()
EF_API void Resize(const VdfNetwork &network)
EF_API bool IsEnabled() const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
EF_API void Invalidate(const _CacheIteratorPredicateFunction &predicate)
static EF_API void SetMemoryUsageLimit(size_t bytes)
Abstract base class for classes that execute a VdfNetwork to compute a requested set of values...
std::vector< VdfMaskedOutput > VdfMaskedOutputVector
EF_API void ClearNodes(const VdfNetwork &network, const tbb::concurrent_vector< VdfIndex > &nodes)
Definition: format.h:4365
EF_API ~EfPageCacheStorage()
#define EF_API
Definition: api.h:25