HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
lruCache.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_VDF_LRU_CACHE_H
8 #define PXR_EXEC_VDF_LRU_CACHE_H
9 
10 /// \file
11 
12 #include "pxr/pxr.h"
13 
14 #include <cstddef>
15 #include <list>
16 
18 
19 ////////////////////////////////////////////////////////////////////////////////
20 ///
21 /// \class VdfLRUCache
22 ///
23 /// A simple cache with a fixed capacity and a least-recently-used eviction
24 /// policy.
25 ///
26 template < typename Key, typename Value, typename Hash >
28 {
29 public:
30  // Non-copyable
31  VdfLRUCache(const VdfLRUCache &) = delete;
32  VdfLRUCache &operator=(const VdfLRUCache &) = delete;
33 
34  // Non-movable
35  VdfLRUCache(VdfLRUCache &&) = delete;
36  VdfLRUCache &operator=(VdfLRUCache &&) = delete;
37 
38  /// Constructs a new cache with a fixed \p capacity.
39  ///
40  explicit VdfLRUCache(size_t capacity) : _capacity(capacity) {}
41 
42  /// Performs a lookup into the cache and returns \c true if the cache
43  /// contains an entry for the given \p key. If the cache does not contain
44  /// and entry for \p key, a new entry will be constructed as long as the
45  /// cache is below capacity. If the cache has reached capacity an existing
46  /// entry will be repurposed for \p key. In this case, \p value will point
47  /// at the evicted entry. and the client will be resonpsible for resetting
48  /// \p value. In all cases, \p value will always point at a valid instance
49  /// of \p Value.
50  ///
51  bool Lookup(const Key &key, Value **value);
52 
53  /// Removes all entries from the cache.
54  ///
55  void Clear();
56 
57 private:
58  // The cache entry stores a hash to accelerate equality comparison, as well
59  // as the key and value for each entry.
60  struct _Entry {
61  _Entry(size_t h, const Key &k) : hash(h), key(k) {}
62 
63  size_t hash;
64  Key key;
65  Value value;
66  };
67 
68  // The sorted list of cache entries. The most recently used entry will
69  // always be at the head of the list.
70  using _List = std::list<_Entry>;
71  _List _list;
72 
73  // The fixed cache capacity. The cache will never grow beyond this size.
74  const size_t _capacity;
75 };
76 
77 ////////////////////////////////////////////////////////////////////////////////
78 
79 template < typename Key, typename Value, typename Hash >
80 bool
82 {
83  // Hash the key. We will use this hash as an early out for
84  // equality comparison.
85  const size_t hash = Hash()(key);
86 
87  // Iterate over all the recently used entries.
88  typename _List::iterator it = _list.begin();
89  for (; it != _list.end(); ++it) {
90  // If the hash and key compare equal, we have found a matching entry.
91  if (it->hash == hash && it->key == key) {
92  // If this entry isn't already at the head of the list, move it
93  // there. This way, the list always stays sorted in order of most
94  // recent usage.
95  if (it != _list.begin()) {
96  _list.splice(_list.begin(), _list, it);
97  }
98 
99  // Return a pointer to the value at the current entry.
100  *value = &it->value;
101  return true;
102  }
103  }
104 
105  // If we were unable to find a matching entry and the list is below
106  // capacity, let's insert a new entry.
107  if (_list.size() < _capacity) {
108  _list.emplace_front(hash, key);
109  }
110 
111  // If the list has reached capacity, reuse the last entry by first moving
112  // it to the front.
113  else {
114  _list.splice(_list.begin(), _list, --_list.end());
115  _list.front().hash = hash;
116  _list.front().key = key;
117  }
118 
119  // Return a pointer to the new value entry.
120  *value = &_list.front().value;
121  return false;
122 }
123 
124 template < typename Key, typename Value, typename Hash >
125 void
127 {
128  _list.clear();
129 }
130 
132 
133 #endif
STATIC_INLINE size_t Hash(const char *s, size_t len)
Definition: farmhash.h:2099
void Clear()
Definition: lruCache.h:126
VdfLRUCache(size_t capacity)
Definition: lruCache.h:40
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
GLsizei const GLfloat * value
Definition: glcorearb.h:824
bool Lookup(const Key &key, Value **value)
Definition: lruCache.h:81
VdfLRUCache(const VdfLRUCache &)=delete
A generic, discriminated value, whose type may be queried dynamically.
Definition: Value.h:45
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
VdfLRUCache & operator=(const VdfLRUCache &)=delete
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74