HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_CappedCache.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_CappedCache.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __UT_CappedCache__
12 #define __UT_CappedCache__
13 
14 #include "UT_API.h"
15 #include "UT_Cache.h"
16 #include "UT_StringHolder.h"
17 #include "UT_IntrusivePtr.h"
18 #include "UT_Lock.h"
19 #include "UT_SpinLock.h"
20 #include "UT_ConcurrentHashMap.h"
21 
23 
25 //typedef UT_Lock UT_CappedLock;
26 
27 /// Base class for search keys for UT_CappedCache
29  : public UT_IntrusiveRefCounter<UT_CappedKey>
30 {
31 public:
32  UT_CappedKey();
33  virtual ~UT_CappedKey();
34 
35  /// The duplicate() method should return a copy of the key.
36  virtual UT_CappedKey *duplicate() const = 0;
37  /// Return a hash for the key
38  virtual unsigned int getHash() const = 0;
39  /// Test equality
40  virtual bool isEqual(const UT_CappedKey &key) const = 0;
41 
42 protected:
43  // The copy constructor is used by subclasses to clone themselves
44  UT_CappedKey(const UT_CappedKey &) = default;
45  UT_CappedKey &operator=(const UT_CappedKey &) = delete;
46 private:
47 };
49 
50 /// Base class for items in the UT_CappedCache
52  : public UT_IntrusiveRefCounter<UT_CappedItem>
53 {
54 public:
55  UT_CappedItem();
56  virtual ~UT_CappedItem();
57 
58  UT_CappedItem(const UT_CappedItem &) = delete;
59  UT_CappedItem &operator=(const UT_CappedItem &) = delete;
60 
61  /// Query the memory used by the cache item. This should be constant over
62  /// the life of the item.
63  virtual int64 getMemoryUsage() const = 0;
64 private:
65 };
67 
68 /// A thread safe memory limited cache
69 ///
70 /// This class stores a map of UT_CappedItem objects which are queried by
71 /// UT_CappedKey objects. In addition, the cache is an LRU, memory limited
72 /// cache. The cache tracks memory used by each UT_CappedItem to keep memory
73 /// usage limited to the given threshold.
74 /// @note This class conforms to the UT_Cache interface.
76 {
77 public:
78  UT_CappedCache(const char *name, int64 size_in_mb=32);
79  ~UT_CappedCache() override;
80 
81  UT_CappedCache(const UT_CappedCache &) = delete;
82  UT_CappedCache &operator=(const UT_CappedCache &) = delete;
83 
84  /// Clear the cache
85  void clear();
86 
87  /// Number of entries in the cache
88  exint entries() const { return myMap.size(); }
89 
90  /// Return the number of entries in the list. This should match the
91  /// entries in the map.
92  exint getListEntries() const { return myEntries; }
93 
94  /// Find an item in the cache
95  UT_CappedItemHandle findItem(const UT_CappedKey &key);
96 
97  /// Add an item to the cache. The returned item may not be the item passed
98  /// as an argument. This may happen if two threads attempt to add the same
99  /// item at the same time (i.e. the keys are equivalent, but the items may
100  /// be different).
101  UT_CappedItemHandle addItem(const UT_CappedKey &key,
102  const UT_CappedItemHandle &item);
103 
104  /// Remove an item from the cache
105  void deleteItem(const UT_CappedKey &key);
106 
107  /// @{
108  /// API from UT_Cache
109  const char *utGetCacheName() const override { return myName; }
110  bool utHasMaxSize() const override { return true; }
111  int64 utGetCurrentSize() const override
112  { return myMemUsage; }
113  int64 utGetMaxSize() const override
114  { return myMaxUsage; }
115  void utSetMaxSize(int64 bytes) override;
117  /// @}
118 
119  /// Thread safe iteration over all items in the cache.
120  /// This method takes a templated class that has a () operator to process
121  /// entries from the traversal. The () operator should return a bool, true
122  /// if the iteration should continue, or false if the traversal can stop.
123  /// For example: @code
124  /// class MemoryCounter
125  /// {
126  /// public:
127  /// MemoryCounter() : myMemory(0) {}
128  /// bool operator()(const UT_CappedKeyHandle &key,
129  /// const UT_CappedItemHandle &handle)
130  /// {
131  /// myMemory += item->getMemoryUsage();
132  /// return true;
133  /// }
134  /// int64 getMemoryUsage() const { return myMemory; }
135  /// int64 myMemory;
136  /// };
137  /// static int64 computeStoredMemory(UT_CappedCache &cache)
138  /// {
139  /// MemoryCounter task;
140  /// cache.threadSafeTraversal(task);
141  /// return task.getMemory();
142  /// }
143  /// @endcode
144  /// @note It is possible to call some methods which alter the map.
145  /// However, other methods will result in a corrupt iteration.
146  /// - @c deleteItem @n
147  /// It is safe to call deleteItem on the current item. However, if
148  /// deleteItem is called, and your task takes const-references to the
149  /// keys/items, these may become invalid.
150  /// - @c findItem @c addItem @n
151  /// This may have a side effect of re-ordering the list, meaning
152  /// iteration will be corrupted.
153  template <typename T>
154  void threadSafeTraversal(T &task)
155  {
156  UT_AutoLock lock(myLock);
157  ut_CappedBin *curr=myHead;
158  ut_CappedBin *next;
159  exint n = myEntries;
160  for (exint i = 0; i < n; ++i, curr = next)
161  {
162  next = curr->myNext;
163  if (!task(curr->getKey(), curr->getItem()))
164  break;
165  }
166  }
167 
168 private:
169  class ut_CappedBin {
170  public:
171  ut_CappedBin(const UT_CappedKeyHandle &key,
172  const UT_CappedItemHandle &item)
173  : myKey(key)
174  , myItem(item)
175  , myPrev(NULL)
176  , myNext(NULL)
177  , myTimeStamp(0)
178  {
179  }
180  ~ut_CappedBin()
181  {
182  }
183 
184  const UT_CappedKeyHandle &getKey() const { return myKey; }
185  const UT_CappedItemHandle &getItem() const { return myItem; }
186 
187  exint getTimeStamp() const { return myTimeStamp; }
188  void setTimeStamp(exint t) { myTimeStamp = t; }
189 
190  bool isNearHead(exint head, exint watermark) const
191  {
192  return head - myTimeStamp <= watermark;
193  }
194 
195  private:
196  UT_CappedKeyHandle myKey;
197  UT_CappedItemHandle myItem;
198  ut_CappedBin *myPrev;
199  ut_CappedBin *myNext;
200  exint myTimeStamp;
201  friend class UT_CappedCache; // For links
202  };
203  class ut_cappedKeyCompare
204  {
205  public:
206  static size_t hash(const UT_CappedKey *a)
207  { return (size_t)a->getHash(); }
208  static bool equal(const UT_CappedKey *a, const UT_CappedKey *b)
209  { return a->isEqual(*b); }
210  };
211  typedef UT_ConcurrentHashMap<const UT_CappedKey *,
212  ut_CappedBin *,
213  ut_cappedKeyCompare> ut_CappedMap;
214 
215 private:
216  void pruneItems();
217  /// @{
218  /// List maintenance
219  void addItem(ut_CappedBin *bin);
220  void accessItem(ut_CappedBin *bin);
221  void removeAndDeleteItem(ut_CappedBin *bin);
222  void insertItem(ut_CappedBin *bin);
223  void unlinkItem(ut_CappedBin *bin);
224  /// @}
225 
226  UT_CappedLock myLock;
227  UT_CappedLock myPruneLock;
228  ut_CappedMap myMap;
229  UT_StringHolder myName;
230  ut_CappedBin *volatile myHead;
231  volatile int64 myMemUsage;
232  int64 myMaxUsage;
233  exint myHeadTime;
234  exint myQuarterEntries;
235  exint myEntries;
236 };
237 
238 #endif
exint entries() const
Number of entries in the cache.
UT_RecursiveSpinLock UT_CappedLock
UT_StringArray JOINTS head
int64 utGetMaxSize() const override
Base class for search keys for UT_CappedCache.
virtual bool isEqual(const UT_CappedKey &key) const =0
Test equality.
int64 exint
Definition: SYS_Types.h:125
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
IMATH_HOSTDEVICE constexpr bool equal(T1 a, T2 b, T3 t) IMATH_NOEXCEPT
Definition: ImathFun.h:105
#define UT_API
Definition: UT_API.h:14
A reference counter base class for use with UT_IntrusivePtr.
UT_IntrusiveRefCounter & operator=(const UT_IntrusiveRefCounter &) noexcept
Assignment operator: Does not modify counter.
virtual int64 utReduceCacheSizeBy(int64 amount)=0
GLdouble n
Definition: glcorearb.h:2008
void threadSafeTraversal(T &task)
long long int64
Definition: SYS_Types.h:116
virtual unsigned int getHash() const =0
Return a hash for the key.
GLuint const GLchar * name
Definition: glcorearb.h:786
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
Common base class for various caches.
Definition: UT_Cache.h:21
GLdouble t
Definition: glad.h:2397
#define UT_ConcurrentHashMap
bool utHasMaxSize() const override
virtual void utSetMaxSize(int64)
Definition: UT_Cache.h:48
const char * utGetCacheName() const override
exint getListEntries() const
Base class for items in the UT_CappedCache.
int64 utGetCurrentSize() const override
Definition: format.h:2459
UT_Cache & operator=(const UT_Cache &)=delete