Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
ObjCache Class Reference

Cache for objects. More...

#include <objcache.h>

Classes

struct  CacheNode
 
struct  HashNode
 

Public Member Functions

 ObjCache (unsigned int logSize)
 
 ~ObjCache ()
 
int add (void *obj, void **victim)
 
void use (int handle)
 
void del (int handle)
 
void printLRU ()
 
void printStats ()
 
int size () const
 
int count () const
 
int hits () const
 
int misses () const
 

Private Member Functions

void moveToFront (int index)
 
unsigned int hash (void *addr)
 
HashNodehashFind (void *obj)
 
HashNodehashInsert (void *obj)
 
void hashRemove (void *obj)
 

Private Attributes

CacheNodem_cache
 
HashNodem_hash
 
int m_head
 
int m_tail
 
int m_size
 
int m_count
 
int m_freeHashNodes
 
int m_freeCacheNodes
 
int m_lastHandle
 
int m_misses
 
int m_hits
 

Detailed Description

Cache for objects.

This cache is used to decide which objects should remain in memory. It uses a least recently used policy (LRU) to decide which object should make room for a new object when the cache is full. An object should be added using add(), and then use() should be called when the object is used.

Definition at line 33 of file objcache.h.

Constructor & Destructor Documentation

ObjCache::ObjCache ( unsigned int  logSize)

Creates the cache. The number of elements in the cache is 2 to the power of logSize.

Definition at line 28 of file objcache.cpp.

29  : m_head(-1), m_tail(-1), //m_numEntries(0),
30  m_size(1<<logSize), m_count(0), m_freeHashNodes(0), m_freeCacheNodes(0),
31  m_lastHandle(-1)
32 {
33  int i;
34  m_cache = new CacheNode[m_size];
35  m_hash = new HashNode[m_size];
36  // add all items to list of free buckets
37  for (i=0;i<m_size-1;i++)
38  {
39  m_hash[i].nextHash = i+1;
40  m_cache[i].next = i+1;
41  }
42  m_misses = 0;
43  m_hits = 0;
44 }
int m_lastHandle
Definition: objcache.h:121
int m_head
Definition: objcache.h:115
int m_tail
Definition: objcache.h:116
CacheNode * m_cache
Definition: objcache.h:113
int m_count
Definition: objcache.h:118
int m_freeHashNodes
Definition: objcache.h:119
HashNode * m_hash
Definition: objcache.h:114
int m_misses
Definition: objcache.h:122
int m_size
Definition: objcache.h:117
int m_hits
Definition: objcache.h:123
int m_freeCacheNodes
Definition: objcache.h:120
ObjCache::~ObjCache ( )

Deletes the cache and free all internal data-structures used.

Definition at line 46 of file objcache.cpp.

47 {
48  delete[] m_cache;
49  delete[] m_hash;
50 }
CacheNode * m_cache
Definition: objcache.h:113
HashNode * m_hash
Definition: objcache.h:114

Member Function Documentation

int ObjCache::add ( void *  obj,
void **  victim 
)

Adds obj to the cache. When victim is not null, this object is removed from the cache to make room for obj. Returns a handle to the object, which can be used by the use() function, each time the object is used.

Definition at line 52 of file objcache.cpp.

53 {
54  *victim=0;
55 
56  HashNode *hnode = hashFind(obj);
57  //printf("hnode=%p\n",hnode);
58  if (hnode) // move object to the front of the LRU list, since it is used
59  // most recently
60  {
61  //printf("moveToFront=%d\n",hnode->index);
62  moveToFront(hnode->index);
63  m_hits++;
64  }
65  else // object not in the cache.
66  {
67  void *lruObj=0;
68  if (m_freeCacheNodes!=-1) // cache not full -> add element to the cache
69  {
70  // remove element from free list
71  int index = m_freeCacheNodes;
73 
74  // add to head of the list
75  if (m_tail==-1)
76  {
77  m_tail = index;
78  }
79  m_cache[index].prev = -1;
81  if (m_head!=-1)
82  {
84  }
85  m_head = index;
86  m_count++;
87  }
88  else // cache full -> replace element in the cache
89  {
90  //printf("Cache full!\n");
91  lruObj = m_cache[m_tail].obj;
92  hashRemove(lruObj);
93  moveToFront(m_tail); // m_tail indexes the emptied element, which becomes m_head
94  }
95  //printf("numEntries=%d size=%d\n",m_numEntries,m_size);
96  m_cache[m_head].obj = obj;
97  hnode = hashInsert(obj);
98  hnode->index = m_head;
99  *victim = lruObj;
100  m_misses++;
101  }
102  return m_head;
103 }
int m_head
Definition: objcache.h:115
int m_tail
Definition: objcache.h:116
void hashRemove(void *obj)
Definition: objcache.cpp:255
CacheNode * m_cache
Definition: objcache.h:113
int m_count
Definition: objcache.h:118
void moveToFront(int index)
Definition: objcache.cpp:155
int m_misses
Definition: objcache.h:122
int m_hits
Definition: objcache.h:123
HashNode * hashInsert(void *obj)
Definition: objcache.cpp:225
int m_freeCacheNodes
Definition: objcache.h:120
HashNode * hashFind(void *obj)
Definition: objcache.cpp:206
int ObjCache::count ( ) const
inline

number of elements in the cache

Definition at line 94 of file objcache.h.

94 { return m_count; }
int m_count
Definition: objcache.h:118
void ObjCache::del ( int  handle)

Removes the item identified by handle from the cache.

See also
add()

Definition at line 105 of file objcache.cpp.

106 {
107  assert(index!=-1);
108  assert(m_cache[index].obj!=0);
109  hashRemove(m_cache[index].obj);
112  if (m_head==-1)
113  m_tail=-1;
114  else
115  m_cache[m_head].prev=-1;
116  m_cache[index].obj=0;
117  m_cache[index].prev=-1;
120  m_count--;
121 }
int m_head
Definition: objcache.h:115
int m_tail
Definition: objcache.h:116
void hashRemove(void *obj)
Definition: objcache.cpp:255
CacheNode * m_cache
Definition: objcache.h:113
int m_count
Definition: objcache.h:118
void moveToFront(int index)
Definition: objcache.cpp:155
int m_freeCacheNodes
Definition: objcache.h:120
unsigned int ObjCache::hash ( void *  addr)
private

Definition at line 175 of file objcache.cpp.

176 {
177  static bool isPtr64 = sizeof(addr)==8;
178  if (isPtr64)
179  {
180  uint64 key = (uint64)addr;
181  // Thomas Wang's 64 bit Mix Function
182  key += ~(key << 32);
183  key ^= (key >> 22);
184  key += ~(key << 13);
185  key ^= (key >> 8);
186  key += (key << 3);
187  key ^= (key >> 15);
188  key += ~(key << 27);
189  key ^= (key >> 31);
190  return (unsigned int)(key & (m_size-1));
191  }
192  else
193  {
194  // Thomas Wang's 32 bit Mix Function
195  uintptr_t key = (uintptr_t)addr;
196  key += ~(key << 15);
197  key ^= (key >> 10);
198  key += (key << 3);
199  key ^= (key >> 6);
200  key += ~(key << 11);
201  key ^= (key >> 16);
202  return (unsigned int)(key & (m_size-1));
203  }
204 }
def key(type, name=None)
Definition: graph.py:13
int m_size
Definition: objcache.h:117
unsigned long long uint64
Definition: qglobal.h:361
constexpr std::enable_if_t< are_cv_compatible< TO, FROM >::value, std::add_pointer_t< std::remove_pointer_t< TO > > > addr(FROM &from)
Definition: ensurePointer.h:35
ObjCache::HashNode * ObjCache::hashFind ( void *  obj)
private

Definition at line 206 of file objcache.cpp.

207 {
208  HashNode *node = 0;
209  int index = m_hash[hash(obj)].head;
210  //printf("hashFind: obj=%p index=%d\n",obj,index);
211  while (index!=-1 &&
212  m_hash[index].obj!=obj
213  ) // search for right object in the list
214  {
215  index = m_hash[index].nextHash;
216  }
217  // found the obj at index, so it is in the cache!
218  if (index!=-1)
219  {
220  node = &m_hash[index];
221  }
222  return node;
223 }
unsigned int hash(void *addr)
Definition: objcache.cpp:175
HashNode * m_hash
Definition: objcache.h:114
ObjCache::HashNode * ObjCache::hashInsert ( void *  obj)
private

Definition at line 225 of file objcache.cpp.

226 {
227  int index = hash(obj);
228  //printf("Inserting %p index=%d\n",obj,index);
229 
230  // remove element from empty list
231  int newElement = m_freeHashNodes;
232  assert(newElement!=-1);
234 
235  if (m_hash[index].head!=-1) // hash collision -> goto end of the list
236  {
237  index = m_hash[index].head;
238  while (m_hash[index].nextHash!=-1)
239  {
240  index = m_hash[index].nextHash;
241  }
242  // add to end of the list
243  m_hash[index].nextHash = newElement;
244  }
245  else // first element in the hash list
246  {
247  m_hash[index].head = newElement;
248  }
249  // add to the end of the list
250  m_hash[newElement].nextHash = -1;
251  m_hash[newElement].obj = obj;
252  return &m_hash[newElement];
253 }
unsigned int hash(void *addr)
Definition: objcache.cpp:175
int m_freeHashNodes
Definition: objcache.h:119
HashNode * m_hash
Definition: objcache.h:114
void ObjCache::hashRemove ( void *  obj)
private

Definition at line 255 of file objcache.cpp.

256 {
257  int index = hash(obj);
258 
259  // find element
260  int curIndex = m_hash[index].head;
261  int prevIndex=-1;
262  while (m_hash[curIndex].obj!=obj)
263  {
264  prevIndex = curIndex;
265  curIndex = m_hash[curIndex].nextHash;
266  }
267 
268  if (prevIndex==-1) // remove from start
269  {
270  m_hash[index].head = m_hash[curIndex].nextHash;
271  }
272  else // remove in the middle
273  {
274  m_hash[prevIndex].nextHash = m_hash[curIndex].nextHash;
275  }
276 
277  // add curIndex element to empty list
278  m_hash[curIndex].nextHash = m_freeHashNodes;
279  m_hash[curIndex].index = -1;
280  m_hash[curIndex].obj = 0;
281  m_freeHashNodes = curIndex;
282 }
unsigned int hash(void *addr)
Definition: objcache.cpp:175
int m_freeHashNodes
Definition: objcache.h:119
HashNode * m_hash
Definition: objcache.h:114
int ObjCache::hits ( ) const
inline

Definition at line 96 of file objcache.h.

97  {
98  return m_hits;
99  }
int m_hits
Definition: objcache.h:123
int ObjCache::misses ( ) const
inline

Definition at line 100 of file objcache.h.

101  {
102  return m_misses;
103  }
int m_misses
Definition: objcache.h:122
void ObjCache::moveToFront ( int  index)
private

Definition at line 155 of file objcache.cpp.

156 {
157  int prev,next;
158  if (m_head!=index)
159  {
160  next = m_cache[index].next;
161  prev = m_cache[index].prev;
162 
163  // de-chain node at index
164  m_cache[prev].next = next;
165  if (next!=-1) m_cache[next].prev = prev; else m_tail = prev;
166 
167  // add to head
168  m_cache[index].prev = -1;
171  m_head = index;
172  }
173 }
int m_head
Definition: objcache.h:115
int m_tail
Definition: objcache.h:116
CacheNode * m_cache
Definition: objcache.h:113
void ObjCache::printLRU ( )

Debug function. Prints the LRU list

void ObjCache::printStats ( )

Print miss/hits statistics

Definition at line 149 of file objcache.cpp.

150 {
151  cache_stats_printf("ObjCache: hits=%d misses=%d hit ratio=%f\n",m_hits,m_misses,m_hits*100.0/(m_hits+m_misses));
152 }
#define cache_stats_printf
Definition: objcache.cpp:148
int m_misses
Definition: objcache.h:122
int m_hits
Definition: objcache.h:123
int ObjCache::size ( ) const
inline

total size of the cache

Definition at line 91 of file objcache.h.

91 { return m_size; }
int m_size
Definition: objcache.h:117
void ObjCache::use ( int  handle)
inline

Indicates that this object is used. This will move the object to the front of the internal LRU list to make sure it is removed last. The parameter handle is returned when called add().

Definition at line 72 of file objcache.h.

73  {
74  if (handle==m_lastHandle) return;
75  m_lastHandle = handle;
76  m_hits++;
77  moveToFront(handle);
78  }
int m_lastHandle
Definition: objcache.h:121
void moveToFront(int index)
Definition: objcache.cpp:155
int m_hits
Definition: objcache.h:123

Member Data Documentation

CacheNode* ObjCache::m_cache
private

Definition at line 113 of file objcache.h.

int ObjCache::m_count
private

Definition at line 118 of file objcache.h.

int ObjCache::m_freeCacheNodes
private

Definition at line 120 of file objcache.h.

int ObjCache::m_freeHashNodes
private

Definition at line 119 of file objcache.h.

HashNode* ObjCache::m_hash
private

Definition at line 114 of file objcache.h.

int ObjCache::m_head
private

Definition at line 115 of file objcache.h.

int ObjCache::m_hits
private

Definition at line 123 of file objcache.h.

int ObjCache::m_lastHandle
private

Definition at line 121 of file objcache.h.

int ObjCache::m_misses
private

Definition at line 122 of file objcache.h.

int ObjCache::m_size
private

Definition at line 117 of file objcache.h.

int ObjCache::m_tail
private

Definition at line 116 of file objcache.h.


The documentation for this class was generated from the following files: