NTrace
GPU ray tracing framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Hash.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2011, NVIDIA Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of NVIDIA Corporation nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #pragma once
29 #include "base/Math.hpp"
30 #include "base/String.hpp"
31 
32 namespace FW
33 {
34 
35 //------------------------------------------------------------------------
36 
37 template <class T> class Set
38 {
39 private:
40  enum
41  {
42  BlockSize = 8,
43  MinBytes = 32,
44  MaxUsagePct = 60,
45  ThrUsagePct = MaxUsagePct * 3 / 4
46  };
47 
48  enum HashValue
49  {
50  Empty = -1,
51  Removed = -2
52  };
53 
54 public:
55  Set (void) { init(); }
56  Set (const Set<T>& other) { init(); set(other); }
57  ~Set (void) { reset(); }
58 
59  int getSize (void) const { return m_numItems; }
60  bool contains (const T& value) const { return (findSlot(value) != -1); }
61  const T* search (const T& value) const { int slot = findSlot(value); return (slot == -1) ? NULL : &m_values[slot]; }
62  T* search (const T& value) { int slot = findSlot(value); return (slot == -1) ? NULL : &m_values[slot]; }
63  const T& get (const T& value) const { int slot = findSlot(value); FW_ASSERT(slot != -1); return m_values[slot]; }
64  T& get (const T& value) { int slot = findSlot(value); FW_ASSERT(slot != -1); return m_values[slot]; }
65 
66  void clear (void) { m_numItems = 0; m_numNonEmpty = 0; memset(m_hashes, Empty, m_capacity * sizeof(S32)); }
67  void reset (void) { delete[] m_hashes; delete[] m_values; init(); }
68  void setCapacity (int numItems);
69  void compact (void) { setCapacity(m_numItems); }
70  void set (const Set<T>& other);
71 
72  T& add (const T& value) { T& slot = addNoAssign(value); slot = value; return slot; }
73  T& addNoAssign (const T& value);
74  T& remove (const T& value);
75  T replace (const T& value);
76 
77  int findSlot (const T& value) const { return findSlot(value, hash<T>(value) >> 1, false); }
78  int firstSlot (void) const { return nextSlot(-1); }
79  int nextSlot (int slot) const;
80  const T& getSlot (int slot) const { FW_ASSERT(m_hashes[slot] >= 0); return m_values[slot]; }
81  T& getSlot (int slot) { FW_ASSERT(m_hashes[slot] >= 0); return m_values[slot]; }
82 
83  Set<T>& operator= (const Set<T>& other) { set(other); return *this; }
84  const T& operator[] (const T& value) const { return get(value); }
85  T& operator[] (const T& value) { return get(value); }
86 
87 private:
88  void init (void) { m_capacity = 0; m_numItems = 0; m_numNonEmpty = 0; m_hashes = NULL; m_values = NULL; }
89  int findSlot (const T& value, S32 hashValue, bool needEmpty) const;
90  void rehash (int capacity);
91 
92 private:
93  S32 m_capacity;
94  S32 m_numItems;
95  S32 m_numNonEmpty;
96  S32* m_hashes;
97  T* m_values;
98 };
99 
100 //------------------------------------------------------------------------
101 
102 template <class K, class V> struct HashEntry
103 {
104  K key;
105  V value;
106 };
107 
108 //------------------------------------------------------------------------
109 
110 template <class K, class V> class Hash
111 {
112 public:
114 
115 public:
116  Hash (void) {}
117  Hash (const Hash<K, V>& other) { set(other); }
118  ~Hash (void) {}
119 
120  const Set<Entry>& getEntries (void) const { return m_entries; }
121  Set<Entry>& getEntries (void) { return m_entries; }
122  int getSize (void) const { return m_entries.getSize(); }
123  bool contains (const K& key) const { return m_entries.contains(keyEntry(key)); }
124  const Entry* searchEntry (const K& key) const { return m_entries.search(keyEntry(key)); }
125  Entry* searchEntry (const K& key) { return m_entries.search(keyEntry(key)); }
126  const K* searchKey (const K& key) const { const Entry* e = searchEntry(key); return (e) ? &e->key : NULL; }
127  K* searchKey (const K& key) { Entry* e = searchEntry(key); return (e) ? &e->key : NULL; }
128  const V* search (const K& key) const { const Entry* e = searchEntry(key); return (e) ? &e->value : NULL; }
129  V* search (const K& key) { Entry* e = searchEntry(key); return (e) ? &e->value : NULL; }
130  const Entry& getEntry (const K& key) const { return m_entries.get(keyEntry(key)); }
131  Entry& getEntry (const K& key) { return m_entries.get(keyEntry(key)); }
132  const K& getKey (const K& key) const { return getEntry(key).key; }
133  K& getKey (const K& key) { return getEntry(key).key; }
134  const V& get (const K& key) const { return getEntry(key).value; }
135  V& get (const K& key) { return getEntry(key).value; }
136 
137  void clear (void) { m_entries.clear(); }
138  void reset (void) { m_entries.reset(); }
139  void setCapacity (int numItems) { m_entries.setCapacity(numItems); }
140  void compact (void) { m_entries.compact(); }
141  void set (const Hash<K, V>& other) { m_entries.set(other.m_entries); }
142 
143  V& add (const K& key, const V& value) { Entry& slot = m_entries.addNoAssign(keyEntry(key)); slot.key = key; slot.value = value; return slot.value; }
144  V& add (const K& key) { Entry& slot = m_entries.addNoAssign(keyEntry(key)); slot.key = key; return slot.value; }
145  V& remove (const K& key) { return m_entries.remove(keyEntry(key)).value; }
146  V replace (const K& key, const V& value) { Entry e; e.key = key; e.value = value; return m_entries.replace(e).value; }
147 
148  int findSlot (const K& key) const { return m_entries.findSlot(keyEntry(key)); }
149  int firstSlot (void) const { return m_entries.firstSlot(); }
150  int nextSlot (int slot) const { return m_entries.nextSlot(slot); }
151  const Entry& getSlot (int slot) const { return m_entries.getSlot(slot); }
152  Entry& getSlot (int slot) { return m_entries.getSlot(slot); }
153 
154  Hash<K, V>& operator= (const Hash<K, V>& other) { set(other); return *this; }
155  const V& operator[] (const K& key) const { return get(key); }
156  V& operator[] (const K& key) { return get(key); }
157 
158 private:
159  static const Entry& keyEntry (const K& key) { return *(Entry*)&key; }
160 
161 private:
162  Set<Entry> m_entries;
163 };
164 
165 //------------------------------------------------------------------------
166 // Helpers for equals() and hash().
167 //------------------------------------------------------------------------
168 
169 #define FW_HASH_MAGIC (0x9e3779b9u)
170 
171 // By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net.
172 #define FW_JENKINS_MIX(a, b, c) \
173  a -= b; a -= c; a ^= (c>>13); \
174  b -= c; b -= a; b ^= (a<<8); \
175  c -= a; c -= b; c ^= (b>>13); \
176  a -= b; a -= c; a ^= (c>>12); \
177  b -= c; b -= a; b ^= (a<<16); \
178  c -= a; c -= b; c ^= (b>>5); \
179  a -= b; a -= c; a ^= (c>>3); \
180  b -= c; b -= a; b ^= (a<<10); \
181  c -= a; c -= b; c ^= (b>>15);
182 
183 inline U32 hashBits (U32 a, U32 b = FW_HASH_MAGIC, U32 c = 0) { c += FW_HASH_MAGIC; FW_JENKINS_MIX(a, b, c); return c; }
184 inline U32 hashBits (U32 a, U32 b, U32 c, U32 d, U32 e = 0, U32 f = 0) { c += FW_HASH_MAGIC; FW_JENKINS_MIX(a, b, c); a += d; b += e; c += f; FW_JENKINS_MIX(a, b, c); return c; }
185 
186 inline bool equalsBuffer (const void* ptrA, const void* ptrB, int size) { return (memcmp(ptrA, ptrB, size) == 0); }
187 inline bool equalsBuffer (const void* ptrA, int sizeA, const void* ptrB, int sizeB) { return (sizeA == sizeB && memcmp(ptrA, ptrB, sizeA) == 0); }
188 U32 hashBuffer (const void* ptr, int size);
189 U32 hashBufferAlign (const void* ptr, int size);
190 
191 //------------------------------------------------------------------------
192 // Base templates.
193 //------------------------------------------------------------------------
194 
195 template <class T> inline bool equalsArray (const T* ptrA, int sizeA, const T* ptrB, int sizeB);
196 template <class T> inline U32 hashArray (const T* ptr, int size);
197 
198 template <class T> inline bool equals (const T& a, const T& b) { return equalsBuffer(&a, &b, sizeof(T)); }
199 template <class T> inline U32 hash (const T& value) { return hashBuffer(&value, sizeof(T)); }
200 
201 //------------------------------------------------------------------------
202 // Specializations for primitive types.
203 //------------------------------------------------------------------------
204 
205 template <> inline bool equalsArray<S8> (const S8* ptrA, int sizeA, const S8* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(S8), ptrB, sizeB * (int)sizeof(S8)); }
206 template <> inline bool equalsArray<U8> (const U8* ptrA, int sizeA, const U8* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(U8), ptrB, sizeB * (int)sizeof(U8)); }
207 template <> inline bool equalsArray<S16>(const S16* ptrA, int sizeA, const S16* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(S16), ptrB, sizeB * (int)sizeof(S16)); }
208 template <> inline bool equalsArray<U16>(const U16* ptrA, int sizeA, const U16* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(U16), ptrB, sizeB * (int)sizeof(U16)); }
209 template <> inline bool equalsArray<S32>(const S32* ptrA, int sizeA, const S32* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(S32), ptrB, sizeB * (int)sizeof(S32)); }
210 template <> inline bool equalsArray<U32>(const U32* ptrA, int sizeA, const U32* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(U32), ptrB, sizeB * (int)sizeof(U32)); }
211 template <> inline bool equalsArray<F32>(const F32* ptrA, int sizeA, const F32* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(F32), ptrB, sizeB * (int)sizeof(F32)); }
212 template <> inline bool equalsArray<S64>(const S64* ptrA, int sizeA, const S64* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(S64), ptrB, sizeB * (int)sizeof(S64)); }
213 template <> inline bool equalsArray<U64>(const U64* ptrA, int sizeA, const U64* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(U64), ptrB, sizeB * (int)sizeof(U64)); }
214 template <> inline bool equalsArray<F64>(const F64* ptrA, int sizeA, const F64* ptrB, int sizeB) { return equalsBuffer(ptrA, sizeA * (int)sizeof(F64), ptrB, sizeB * (int)sizeof(F64)); }
215 
216 template <> inline U32 hashArray<S8> (const S8* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(S8)); }
217 template <> inline U32 hashArray<U8> (const U8* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(U8)); }
218 template <> inline U32 hashArray<S16> (const S16* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(S16)); }
219 template <> inline U32 hashArray<U16> (const U16* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(U16)); }
220 template <> inline U32 hashArray<S32> (const S32* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(S32)); }
221 template <> inline U32 hashArray<U32> (const U32* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(U32)); }
222 template <> inline U32 hashArray<F32> (const F32* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(F32)); }
223 template <> inline U32 hashArray<S64> (const S64* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(S64)); }
224 template <> inline U32 hashArray<U64> (const U64* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(U64)); }
225 template <> inline U32 hashArray<F64> (const F64* ptr, int size) { return hashBuffer(ptr, size * (int)sizeof(F64)); }
226 
227 template <> inline bool equals<S8> (const S8& a, const S8& b) { return (a == b); }
228 template <> inline bool equals<U8> (const U8& a, const U8& b) { return (a == b); }
229 template <> inline bool equals<S16> (const S16& a, const S16& b) { return (a == b); }
230 template <> inline bool equals<U16> (const U16& a, const U16& b) { return (a == b); }
231 template <> inline bool equals<S32> (const S32& a, const S32& b) { return (a == b); }
232 template <> inline bool equals<U32> (const U32& a, const U32& b) { return (a == b); }
233 template <> inline bool equals<F32> (const F32& a, const F32& b) { return (floatToBits(a) == floatToBits(b)); }
234 template <> inline bool equals<S64> (const S64& a, const S64& b) { return (a == b); }
235 template <> inline bool equals<U64> (const U64& a, const U64& b) { return (a == b); }
236 template <> inline bool equals<F64> (const F64& a, const F64& b) { return (doubleToBits(a) == doubleToBits(b)); }
237 
238 template <> inline U32 hash<S8> (const S8& value) { return hashBits(value); }
239 template <> inline U32 hash<U8> (const U8& value) { return hashBits(value); }
240 template <> inline U32 hash<S16> (const S16& value) { return hashBits(value); }
241 template <> inline U32 hash<U16> (const U16& value) { return hashBits(value); }
242 template <> inline U32 hash<S32> (const S32& value) { return hashBits(value); }
243 template <> inline U32 hash<U32> (const U32& value) { return hashBits(value); }
244 template <> inline U32 hash<F32> (const F32& value) { return hashBits(floatToBits(value)); }
245 template <> inline U32 hash<S64> (const S64& value) { return hashBits((U32)value, (U32)(value >> 32)); }
246 template <> inline U32 hash<U64> (const U64& value) { return hash<S64>((S64)value); }
247 template <> inline U32 hash<F64> (const F64& value) { return hash<U64>(doubleToBits(value)); }
248 
249 //------------------------------------------------------------------------
250 // Specializations for compound types.
251 //------------------------------------------------------------------------
252 
253 template <> inline bool equals<Vec2i> (const Vec2i& a, const Vec2i& b) { return (a == b); }
254 template <> inline bool equals<Vec2f> (const Vec2f& a, const Vec2f& b) { return (equals<F32>(a.x, b.x) && equals<F32>(a.y, b.y)); }
255 template <> inline bool equals<Vec3i> (const Vec3i& a, const Vec3i& b) { return (a == b); }
256 template <> inline bool equals<Vec3f> (const Vec3f& a, const Vec3f& b) { return (equals<F32>(a.x, b.x) && equals<F32>(a.y, b.y) && equals<F32>(a.z, b.z)); }
257 template <> inline bool equals<Vec4i> (const Vec4i& a, const Vec4i& b) { return (a == b); }
258 template <> inline bool equals<Vec4f> (const Vec4f& a, const Vec4f& b) { return (equals<F32>(a.x, b.x) && equals<F32>(a.y, b.y) && equals<F32>(a.z, b.z) && equals<F32>(a.w, b.w)); }
259 template <> inline bool equals<Mat2f> (const Mat2f& a, const Mat2f& b) { return equalsBuffer(&a, &b, sizeof(a)); }
260 template <> inline bool equals<Mat3f> (const Mat3f& a, const Mat3f& b) { return equalsBuffer(&a, &b, sizeof(a)); }
261 template <> inline bool equals<Mat4f> (const Mat4f& a, const Mat4f& b) { return equalsBuffer(&a, &b, sizeof(a)); }
262 template <> inline bool equals<String> (const String& a, const String& b) { return equalsBuffer(a.getPtr(), a.getLength(), b.getPtr(), b.getLength()); }
263 
264 template <> inline U32 hash<Vec2i> (const Vec2i& value) { return hashBits(value.x, value.y); }
265 template <> inline U32 hash<Vec2f> (const Vec2f& value) { return hashBits(floatToBits(value.x), floatToBits(value.y)); }
266 template <> inline U32 hash<Vec3i> (const Vec3i& value) { return hashBits(value.x, value.y, value.z); }
267 template <> inline U32 hash<Vec3f> (const Vec3f& value) { return hashBits(floatToBits(value.x), floatToBits(value.y), floatToBits(value.z)); }
268 template <> inline U32 hash<Vec4i> (const Vec4i& value) { return hashBits(value.x, value.y, value.z, value.w); }
269 template <> inline U32 hash<Vec4f> (const Vec4f& value) { return hashBits(floatToBits(value.x), floatToBits(value.y), floatToBits(value.z), floatToBits(value.w)); }
270 template <> inline U32 hash<Mat2f> (const Mat2f& value) { return hashBufferAlign(&value, sizeof(value)); }
271 template <> inline U32 hash<Mat3f> (const Mat3f& value) { return hashBufferAlign(&value, sizeof(value)); }
272 template <> inline U32 hash<Mat4f> (const Mat4f& value) { return hashBufferAlign(&value, sizeof(value)); }
273 template <> inline U32 hash<String> (const String& value) { return hashBuffer(value.getPtr(), value.getLength()); }
274 
275 //------------------------------------------------------------------------
276 // Partial specializations.
277 //------------------------------------------------------------------------
278 
279 template <class T, class TT> inline bool equals(TT* const& a, TT* const& b) { return (a == b); }
280 template <class T, class TT> inline U32 hash(TT* const& value) { return hashBits((U32)(UPTR)value); }
281 
282 template <class T, class K, class V> inline bool equals(const HashEntry<K, V>& a, const HashEntry<K, V>& b) { return equals<K>(a.key, b.key); }
283 template <class T, class K, class V> inline U32 hash (const HashEntry<K, V>& value) { return hash<K>(value.key); }
284 
285 template <class T, class TT> inline bool equals(const Array<TT>& a, const Array<TT>& b) { return equalsArray<T>(a.getPtr(), a.getSize(), b.getPtr(), b.getSize()); }
286 template <class T, class TT> inline U32 hash(const Array<TT>& value) { return hashArray<T>(value.getPtr(), value.getSize()); }
287 
288 //------------------------------------------------------------------------
289 // GenericHashKey.
290 //------------------------------------------------------------------------
291 
293 {
294  const void* ptr;
296 
297  GenericHashKey(void) : ptr(NULL), size(0) {}
298  GenericHashKey(const void* p, int s) : ptr(p), size(s) { FW_ASSERT(s >= 0); FW_ASSERT(p || !s); }
299  template <class T> GenericHashKey(const T* p) : ptr(p), size(sizeof(T)) { FW_ASSERT(p); }
300 };
301 
302 template <> inline bool equals<GenericHashKey>(const GenericHashKey& a, const GenericHashKey& b) { return equalsBuffer(a.ptr, a.size, b.ptr, b.size); }
303 template <> inline U32 hash<GenericHashKey>(const GenericHashKey& value) { return hashBuffer(value.ptr, value.size); }
304 
305 //------------------------------------------------------------------------
306 // Implementation.
307 //------------------------------------------------------------------------
308 
309 template <class T> void Set<T>::setCapacity(int numItems)
310 {
311  int capacity = BlockSize;
312  S64 limit = (S64)max(numItems, m_numItems, (MinBytes + (S32)sizeof(T) - 1) / (S32)sizeof(T)) * 100;
313  while ((S64)capacity * MaxUsagePct < limit)
314  capacity <<= 1;
315 
316  if (capacity != m_capacity)
317  rehash(capacity);
318 }
319 
320 //------------------------------------------------------------------------
321 
322 template <class T> void Set<T>::set(const Set<T>& other)
323 {
324  if (this == &other)
325  return;
326 
327  clear();
328  if (!other.m_numItems)
329  return;
330 
331  m_capacity = other.m_capacity;
332  m_numItems = other.m_numItems;
333  m_numNonEmpty = other.m_numNonEmpty;
334  m_hashes = new S32[m_capacity];
335  m_values = new T[m_capacity];
336 
337  memcpy(m_hashes, other.m_hashes, m_capacity * sizeof(S32));
338  for (int i = 0; i < m_capacity; i++)
339  m_values[i] = other.m_values[i];
340 }
341 
342 //------------------------------------------------------------------------
343 
344 template <class T> T& Set<T>::addNoAssign(const T& value)
345 {
346  FW_ASSERT(!contains(value));
347 
348  // Empty => allocate.
349 
350  if (!m_capacity)
351  setCapacity(0);
352 
353  // Exceeds MaxUsagePct => rehash.
354 
355  else if ((S64)m_numNonEmpty * 100 >= (S64)m_capacity * MaxUsagePct)
356  {
357  int cap = m_capacity;
358  if ((S64)m_numItems * 100 >= (S64)cap * ThrUsagePct)
359  cap <<= 1;
360  rehash(cap);
361  }
362 
363  // Find slot.
364 
365  S32 hashValue = hash<T>(value) >> 1;
366  int slot = findSlot(value, hashValue, true);
367  FW_ASSERT(m_hashes[slot] < 0);
368 
369  // Add item.
370 
371  m_numItems++;
372  if (m_hashes[slot] == Empty)
373  m_numNonEmpty++;
374 
375  m_hashes[slot] = hashValue;
376  return m_values[slot];
377 }
378 
379 //------------------------------------------------------------------------
380 
381 template <class T> T& Set<T>::remove(const T& value)
382 {
383  int slot = findSlot(value, hash<T>(value) >> 1, false);
384  FW_ASSERT(m_hashes[slot] >= 0);
385 
386  m_numItems--;
387  m_hashes[slot] = Removed;
388  return m_values[slot];
389 }
390 
391 //------------------------------------------------------------------------
392 
393 template <class T> T Set<T>::replace(const T& value)
394 {
395  int slot = findSlot(value, hash<T>(value) >> 1, false);
396  FW_ASSERT(m_hashes[slot] >= 0);
397 
398  T old = m_values[slot];
399  m_values[slot] = value;
400  return old;
401 }
402 
403 //------------------------------------------------------------------------
404 
405 template <class T> int Set<T>::nextSlot(int slot) const
406 {
407  FW_ASSERT(slot >= -1 && slot < m_capacity);
408  for (slot++; slot < m_capacity; slot++)
409  if (m_hashes[slot] >= 0)
410  return slot;
411  return -1;
412 }
413 
414 //------------------------------------------------------------------------
415 
416 template <class T> int Set<T>::findSlot(const T& value, S32 hashValue, bool needEmpty) const
417 {
418  FW_ASSERT(hashValue >= 0);
419  if (!m_capacity)
420  return -1;
421 
422  int blockMask = (m_capacity - 1) & -BlockSize;
423  int firstSlot = hashValue;
424  int firstBlock = firstSlot & blockMask;
425  int blockStep = BlockSize * 3 + ((hashValue >> 17) & (-4 * BlockSize));
426 
427  int block = firstBlock;
428  do
429  {
430  if (needEmpty)
431  {
432  for (int i = 0; i < BlockSize; i++)
433  {
434  int slot = block + ((firstSlot + i) & (BlockSize - 1));
435  if (m_hashes[slot] < 0)
436  return slot;
437  }
438  }
439  else
440  {
441  for (int i = 0; i < BlockSize; i++)
442  {
443  int slot = block + ((firstSlot + i) & (BlockSize - 1));
444  S32 slotHash = m_hashes[slot];
445 
446  if (slotHash == Empty)
447  return -1;
448 
449  if (slotHash == hashValue && equals<T>(m_values[slot], value))
450  return slot;
451  }
452  }
453 
454  block = (block + blockStep) & blockMask;
455  blockStep += BlockSize * 4;
456  }
457  while (block != firstBlock);
458  return -1;
459 }
460 
461 //------------------------------------------------------------------------
462 
463 template <class T> void Set<T>::rehash(int capacity)
464 {
465  FW_ASSERT(capacity >= BlockSize);
466  FW_ASSERT(capacity >= m_numItems);
467 
468  int oldCapacity = m_capacity;
469  S32* oldHashes = m_hashes;
470  T* oldValues = m_values;
471  m_capacity = capacity;
472  m_numNonEmpty = m_numItems;
473  m_hashes = new S32[capacity];
474  m_values = new T[capacity];
475 
476  memset(m_hashes, Empty, capacity * sizeof(S32));
477 
478  for (int i = 0; i < oldCapacity; i++)
479  {
480  S32 oldHash = oldHashes[i];
481  if (oldHash < 0)
482  continue;
483 
484  const T& oldValue = oldValues[i];
485  int slot = findSlot(oldValue, oldHash, true);
486  FW_ASSERT(m_hashes[slot] == Empty);
487 
488  m_hashes[slot] = oldHash;
489  m_values[slot] = oldValue;
490  }
491 
492  delete[] oldHashes;
493  delete[] oldValues;
494 }
495 
496 //------------------------------------------------------------------------
497 
498 template <class T> bool equalsArray(const T* ptrA, int sizeA, const T* ptrB, int sizeB)
499 {
500  if (sizeA != sizeB)
501  return false;
502 
503  for (int i = 0; i < sizeA; i++)
504  if (!equals<T>(ptrA[i], ptrB[i]))
505  return false;
506  return true;
507 }
508 
509 //------------------------------------------------------------------------
510 
511 template <class T> U32 hashArray(const T* ptr, int size)
512 {
513  FW_ASSERT(size >= 0);
514  FW_ASSERT(ptr || !size);
515 
516  U32 a = FW_HASH_MAGIC;
517  U32 b = FW_HASH_MAGIC;
518  U32 c = FW_HASH_MAGIC;
519 
520  while (size >= 3)
521  {
522  a += hash<T>(ptr[0]);
523  b += hash<T>(ptr[1]);
524  c += hash<T>(ptr[2]);
525  FW_JENKINS_MIX(a, b, c);
526  ptr += 3;
527  size -= 3;
528  }
529 
530  switch (size)
531  {
532  case 2: b += hash<T>(ptr[1]);
533  case 1: a += hash<T>(ptr[0]);
534  }
535 
536  c += size;
537  FW_JENKINS_MIX(a, b, c);
538  return c;
539 }
540 
541 //------------------------------------------------------------------------
542 }
Set< T > & operator=(const Set< T > &other)
Definition: Hash.hpp:83
Definition: Hash.hpp:102
int nextSlot(int slot) const
Definition: Hash.hpp:150
bool equalsArray< U64 >(const U64 *ptrA, int sizeA, const U64 *ptrB, int sizeB)
Definition: Hash.hpp:213
U32 floatToBits(F32 a)
Definition: Math.hpp:95
U32 hash< S16 >(const S16 &value)
Definition: Hash.hpp:240
bool contains(const K &key) const
Definition: Hash.hpp:123
#define NULL
Definition: Defs.hpp:39
U32 hashBuffer(const void *ptr, int size)
Definition: Hash.cpp:34
K & getKey(const K &key)
Definition: Hash.hpp:133
const T & operator[](const T &value) const
Definition: Hash.hpp:84
const V & operator[](const K &key) const
Definition: Hash.hpp:155
int findSlot(const T &value) const
Definition: Hash.hpp:77
bool equals< GenericHashKey >(const GenericHashKey &a, const GenericHashKey &b)
Definition: Hash.hpp:302
Entry & getSlot(int slot)
Definition: Hash.hpp:152
__w64 U32 UPTR
Definition: Defs.hpp:106
bool equals< U32 >(const U32 &a, const U32 &b)
Definition: Hash.hpp:232
void set(const Hash< K, V > &other)
Definition: Hash.hpp:141
T * search(const T &value)
Definition: Hash.hpp:62
U32 hashArray< U16 >(const U16 *ptr, int size)
Definition: Hash.hpp:219
int findSlot(const K &key) const
Definition: Hash.hpp:148
~Set(void)
Definition: Hash.hpp:57
bool equalsArray< F64 >(const F64 *ptrA, int sizeA, const F64 *ptrB, int sizeB)
Definition: Hash.hpp:214
bool equals< U16 >(const U16 &a, const U16 &b)
Definition: Hash.hpp:230
Entry & getEntry(const K &key)
Definition: Hash.hpp:131
const Entry * searchEntry(const K &key) const
Definition: Hash.hpp:124
Definition: Hash.hpp:37
Entry * searchEntry(const K &key)
Definition: Hash.hpp:125
bool equalsArray< S16 >(const S16 *ptrA, int sizeA, const S16 *ptrB, int sizeB)
Definition: Hash.hpp:207
bool equalsArray< S64 >(const S64 *ptrA, int sizeA, const S64 *ptrB, int sizeB)
Definition: Hash.hpp:212
bool equals< String >(const String &a, const String &b)
Definition: Hash.hpp:262
void ** ptr
Definition: DLLImports.cpp:74
const T * search(const T &value) const
Definition: Hash.hpp:61
void compact(void)
Definition: Hash.hpp:140
void clear(void)
Definition: Hash.hpp:66
bool equals< U8 >(const U8 &a, const U8 &b)
Definition: Hash.hpp:228
unsigned __int64 U64
Definition: Defs.hpp:97
signed char S8
Definition: Defs.hpp:86
U32 hash(const T &value)
Definition: Hash.hpp:199
double F64
Definition: Defs.hpp:90
U32 hash< Vec4i >(const Vec4i &value)
Definition: Hash.hpp:268
bool equals< U64 >(const U64 &a, const U64 &b)
Definition: Hash.hpp:235
bool equals< Vec2i >(const Vec2i &a, const Vec2i &b)
Definition: Hash.hpp:253
void clear(void)
Definition: Hash.hpp:137
void set(const Set< T > &other)
Definition: Hash.hpp:322
Set< Entry > & getEntries(void)
Definition: Hash.hpp:121
const K & getKey(const K &key) const
Definition: Hash.hpp:132
int firstSlot(void) const
Definition: Hash.hpp:78
Hash< K, V > & operator=(const Hash< K, V > &other)
Definition: Hash.hpp:154
T & add(const T &value)
Definition: Hash.hpp:72
GenericHashKey(const T *p)
Definition: Hash.hpp:299
bool equals< F32 >(const F32 &a, const F32 &b)
Definition: Hash.hpp:233
U32 hash< F32 >(const F32 &value)
Definition: Hash.hpp:244
U32 hash< U64 >(const U64 &value)
Definition: Hash.hpp:246
bool equals< Vec3i >(const Vec3i &a, const Vec3i &b)
Definition: Hash.hpp:255
U32 hashArray< U64 >(const U64 *ptr, int size)
Definition: Hash.hpp:224
T & addNoAssign(const T &value)
Definition: Hash.hpp:344
U32 hash< Vec2i >(const Vec2i &value)
Definition: Hash.hpp:264
T & getSlot(int slot)
Definition: Hash.hpp:81
const Entry & getSlot(int slot) const
Definition: Hash.hpp:151
U32 hashBufferAlign(const void *ptr, int size)
Definition: Hash.cpp:80
HashEntry< K, V > Entry
Definition: Hash.hpp:113
float F32
Definition: Defs.hpp:89
#define FW_HASH_MAGIC
Definition: Hash.hpp:169
Hash(void)
Definition: Hash.hpp:116
bool equalsArray< U32 >(const U32 *ptrA, int sizeA, const U32 *ptrB, int sizeB)
Definition: Hash.hpp:210
U32 hashArray< S8 >(const S8 *ptr, int size)
Definition: Hash.hpp:216
bool contains(const T &value) const
Definition: Hash.hpp:60
bool equals< S64 >(const S64 &a, const S64 &b)
Definition: Hash.hpp:234
GenericHashKey(const void *p, int s)
Definition: Hash.hpp:298
bool equalsBuffer(const void *ptrA, const void *ptrB, int size)
Definition: Hash.hpp:186
signed short S16
Definition: Defs.hpp:87
bool equals< Vec4f >(const Vec4f &a, const Vec4f &b)
Definition: Hash.hpp:258
U32 hash< S64 >(const S64 &value)
Definition: Hash.hpp:245
void setCapacity(int numItems)
Definition: Hash.hpp:309
bool equals< Mat2f >(const Mat2f &a, const Mat2f &b)
Definition: Hash.hpp:259
bool equalsArray< S32 >(const S32 *ptrA, int sizeA, const S32 *ptrB, int sizeB)
Definition: Hash.hpp:209
bool equalsArray< U8 >(const U8 *ptrA, int sizeA, const U8 *ptrB, int sizeB)
Definition: Hash.hpp:206
bool equals< Mat4f >(const Mat4f &a, const Mat4f &b)
Definition: Hash.hpp:261
U32 hashArray< U8 >(const U8 *ptr, int size)
Definition: Hash.hpp:217
FW_CUDA_FUNC T max(const VectorBase< T, L, S > &v)
Definition: Math.hpp:462
U32 hash< Vec3i >(const Vec3i &value)
Definition: Hash.hpp:266
#define FW_ASSERT(X)
Definition: Defs.hpp:67
U32 hashArray< F32 >(const F32 *ptr, int size)
Definition: Hash.hpp:222
signed int S32
Definition: Defs.hpp:88
int nextSlot(int slot) const
Definition: Hash.hpp:405
GenericHashKey(void)
Definition: Hash.hpp:297
const Entry & getEntry(const K &key) const
Definition: Hash.hpp:130
bool equals< Vec3f >(const Vec3f &a, const Vec3f &b)
Definition: Hash.hpp:256
const T & getSlot(int slot) const
Definition: Hash.hpp:80
U32 hashArray< S64 >(const S64 *ptr, int size)
Definition: Hash.hpp:223
T replace(const T &value)
Definition: Hash.hpp:393
U32 hashArray< U32 >(const U32 *ptr, int size)
Definition: Hash.hpp:221
U32 hashArray< S32 >(const S32 *ptr, int size)
Definition: Hash.hpp:220
bool equals(const T &a, const T &b)
Definition: Hash.hpp:198
Set(const Set< T > &other)
Definition: Hash.hpp:56
int getSize(void) const
Definition: Hash.hpp:122
FW_CUDA_FUNC U64 doubleToBits(F64 a)
Definition: Math.hpp:63
V & add(const K &key, const V &value)
Definition: Hash.hpp:143
signed __int64 S64
Definition: Defs.hpp:98
unsigned int U32
Definition: Defs.hpp:85
V * search(const K &key)
Definition: Hash.hpp:129
bool equals< S8 >(const S8 &a, const S8 &b)
Definition: Hash.hpp:227
K key
Definition: Hash.hpp:104
U32 hashBits(U32 a, U32 b=FW_HASH_MAGIC, U32 c=0)
Definition: Hash.hpp:183
U32 hash< F64 >(const F64 &value)
Definition: Hash.hpp:247
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void p CUfunction unsigned int bytes CUtexref pTexRef CUtexref CUarray unsigned int Flags CUtexref int CUaddress_mode am CUtexref unsigned int Flags CUaddress_mode CUtexref int dim CUarray_format int CUtexref hTexRef CUfunction unsigned int numbytes CUfunction int float value CUfunction int CUtexref hTexRef CUfunction f
Definition: DLLImports.inl:88
bool equals< S32 >(const S32 &a, const S32 &b)
Definition: Hash.hpp:231
K * searchKey(const K &key)
Definition: Hash.hpp:127
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void p CUfunction unsigned int bytes CUtexref pTexRef CUtexref CUarray unsigned int Flags CUtexref int CUaddress_mode am CUtexref unsigned int Flags CUaddress_mode CUtexref int dim CUarray_format int CUtexref hTexRef CUfunction unsigned int numbytes CUfunction int float value
Definition: DLLImports.inl:84
U32 hash< U8 >(const U8 &value)
Definition: Hash.hpp:239
U32 hashArray(const T *ptr, int size)
Definition: Hash.hpp:511
U32 hash< Mat2f >(const Mat2f &value)
Definition: Hash.hpp:270
const K * searchKey(const K &key) const
Definition: Hash.hpp:126
V & add(const K &key)
Definition: Hash.hpp:144
V replace(const K &key, const V &value)
Definition: Hash.hpp:146
U32 hashArray< S16 >(const S16 *ptr, int size)
Definition: Hash.hpp:218
bool equalsArray< U16 >(const U16 *ptrA, int sizeA, const U16 *ptrB, int sizeB)
Definition: Hash.hpp:208
void compact(void)
Definition: Hash.hpp:69
unsigned char U8
Definition: Defs.hpp:83
U32 hash< S8 >(const S8 &value)
Definition: Hash.hpp:238
unsigned short U16
Definition: Defs.hpp:84
int getSize(void) const
Definition: Hash.hpp:59
U32 hash< String >(const String &value)
Definition: Hash.hpp:273
U32 hash< Mat4f >(const Mat4f &value)
Definition: Hash.hpp:272
bool equals< F64 >(const F64 &a, const F64 &b)
Definition: Hash.hpp:236
bool equalsArray< F32 >(const F32 *ptrA, int sizeA, const F32 *ptrB, int sizeB)
Definition: Hash.hpp:211
const void * ptr
Definition: Hash.hpp:294
V value
Definition: Hash.hpp:105
T & remove(const T &value)
Definition: Hash.hpp:381
const V * search(const K &key) const
Definition: Hash.hpp:128
#define FW_JENKINS_MIX(a, b, c)
Definition: Hash.hpp:172
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void * p
Definition: DLLImports.inl:66
U32 hash< GenericHashKey >(const GenericHashKey &value)
Definition: Hash.hpp:303
U32 hashArray< F64 >(const F64 *ptr, int size)
Definition: Hash.hpp:225
Hash(const Hash< K, V > &other)
Definition: Hash.hpp:117
U32 hash< Mat3f >(const Mat3f &value)
Definition: Hash.hpp:271
U32 hash< U32 >(const U32 &value)
Definition: Hash.hpp:243
U32 hash< Vec3f >(const Vec3f &value)
Definition: Hash.hpp:267
void setCapacity(int numItems)
Definition: Hash.hpp:139
bool equalsArray(const T *ptrA, int sizeA, const T *ptrB, int sizeB)
Definition: Hash.hpp:498
const T * getPtr(S32idx=0) const
const Set< Entry > & getEntries(void) const
Definition: Hash.hpp:120
~Hash(void)
Definition: Hash.hpp:118
U32 hash< Vec2f >(const Vec2f &value)
Definition: Hash.hpp:265
bool equals< Mat3f >(const Mat3f &a, const Mat3f &b)
Definition: Hash.hpp:260
CUdevice int ordinal char int CUdevice dev CUdevprop CUdevice dev CUcontext ctx CUcontext ctx CUcontext pctx CUmodule const void image CUmodule const void fatCubin CUfunction CUmodule const char name void p CUfunction unsigned int bytes CUtexref pTexRef CUtexref CUarray unsigned int Flags CUtexref int CUaddress_mode am CUtexref unsigned int Flags CUaddress_mode CUtexref int dim CUarray_format int CUtexref hTexRef CUfunction unsigned int numbytes CUfunction int float value CUfunction int CUtexref hTexRef CUfunction int int grid_height CUevent unsigned int Flags CUevent hEvent CUevent hEvent CUstream unsigned int Flags CUstream hStream GLuint bufferobj unsigned int CUdevice dev CUdeviceptr unsigned int CUmodule const char name CUdeviceptr unsigned int bytesize CUdeviceptr dptr void unsigned int bytesize void CUdeviceptr unsigned int ByteCount CUarray unsigned int CUdeviceptr unsigned int ByteCount CUarray unsigned int const void unsigned int ByteCount CUarray unsigned int CUarray unsigned int unsigned int ByteCount void CUarray unsigned int unsigned int CUstream hStream const CUDA_MEMCPY2D pCopy CUdeviceptr const void unsigned int CUstream hStream const CUDA_MEMCPY2D CUstream hStream CUdeviceptr unsigned char unsigned int N CUdeviceptr unsigned int unsigned int N CUdeviceptr unsigned int unsigned short unsigned int unsigned int Height CUarray const CUDA_ARRAY_DESCRIPTOR pAllocateArray CUarray const CUDA_ARRAY3D_DESCRIPTOR pAllocateArray unsigned int CUtexref CUdeviceptr unsigned int bytes CUcontext unsigned int CUdevice device GLenum texture GLenum GLuint buffer GLenum GLuint renderbuffer GLenum GLsizeiptr size
Definition: DLLImports.inl:319
U32 hash< U16 >(const U16 &value)
Definition: Hash.hpp:241
U32 hash< S32 >(const S32 &value)
Definition: Hash.hpp:242
void reset(void)
Definition: Hash.hpp:67
Set(void)
Definition: Hash.hpp:55
S32 getSize(void) const
bool equals< Vec2f >(const Vec2f &a, const Vec2f &b)
Definition: Hash.hpp:254
bool equals< Vec4i >(const Vec4i &a, const Vec4i &b)
Definition: Hash.hpp:257
int firstSlot(void) const
Definition: Hash.hpp:149
bool equalsArray< S8 >(const S8 *ptrA, int sizeA, const S8 *ptrB, int sizeB)
Definition: Hash.hpp:205
void reset(void)
Definition: Hash.hpp:138
U32 hash< Vec4f >(const Vec4f &value)
Definition: Hash.hpp:269
bool equals< S16 >(const S16 &a, const S16 &b)
Definition: Hash.hpp:229