Bullet Collision Detection & Physics Library
btHashMap.h
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#ifndef BT_HASH_MAP_H
17#define BT_HASH_MAP_H
18
19#include <string>
21
24{
25 std::string m_string1;
26 unsigned int m_hash;
27
28 SIMD_FORCE_INLINE unsigned int getHash() const
29 {
30 return m_hash;
31 }
32
34 {
35 m_string1 = "";
36 m_hash = 0;
37 }
38 btHashString(const char* name)
40 {
41 /* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */
42 static const unsigned int InitialFNV = 2166136261u;
43 static const unsigned int FNVMultiple = 16777619u;
44
45 /* Fowler / Noll / Vo (FNV) Hash */
46 unsigned int hash = InitialFNV;
47
48 for (int i = 0; m_string1.c_str()[i]; i++)
49 {
50 hash = hash ^ (m_string1.c_str()[i]); /* xor the low 8 bits */
51 hash = hash * FNVMultiple; /* multiply by the magic number */
52 }
53 m_hash = hash;
54 }
55
56 bool equals(const btHashString& other) const
57 {
58 return (m_string1 == other.m_string1);
59 }
60};
61
62const int BT_HASH_NULL = 0xffffffff;
63
65{
66 int m_uid;
67
68public:
70 {
71 }
72
74 {
75 }
76
77 int getUid1() const
78 {
79 return m_uid;
80 }
81
82 void setUid1(int uid)
83 {
84 m_uid = uid;
85 }
86
87 bool equals(const btHashInt& other) const
88 {
89 return getUid1() == other.getUid1();
90 }
91 //to our success
92 SIMD_FORCE_INLINE unsigned int getHash() const
93 {
94 unsigned int key = m_uid;
95 // Thomas Wang's hash
96 key += ~(key << 15);
97 key ^= (key >> 10);
98 key += (key << 3);
99 key ^= (key >> 6);
100 key += ~(key << 11);
101 key ^= (key >> 16);
102
103 return key;
104 }
105};
106
108{
109 union {
110 const void* m_pointer;
111 unsigned int m_hashValues[2];
112 };
113
114public:
115 btHashPtr(const void* ptr)
116 : m_pointer(ptr)
117 {
118 }
119
120 const void* getPointer() const
121 {
122 return m_pointer;
123 }
124
125 bool equals(const btHashPtr& other) const
126 {
127 return getPointer() == other.getPointer();
128 }
129
130 //to our success
131 SIMD_FORCE_INLINE unsigned int getHash() const
132 {
133 const bool VOID_IS_8 = ((sizeof(void*) == 8));
134
135 unsigned int key = VOID_IS_8 ? m_hashValues[0] + m_hashValues[1] : m_hashValues[0];
136 // Thomas Wang's hash
137 key += ~(key << 15);
138 key ^= (key >> 10);
139 key += (key << 3);
140 key ^= (key >> 6);
141 key += ~(key << 11);
142 key ^= (key >> 16);
143 return key;
144 }
145};
146
147template <class Value>
149{
150 int m_uid;
151
152public:
154 {
155 }
156
157 int getUid1() const
158 {
159 return m_uid;
160 }
161
162 bool equals(const btHashKeyPtr<Value>& other) const
163 {
164 return getUid1() == other.getUid1();
165 }
166
167 //to our success
168 SIMD_FORCE_INLINE unsigned int getHash() const
169 {
170 unsigned int key = m_uid;
171 // Thomas Wang's hash
172 key += ~(key << 15);
173 key ^= (key >> 10);
174 key += (key << 3);
175 key ^= (key >> 6);
176 key += ~(key << 11);
177 key ^= (key >> 16);
178 return key;
179 }
180};
181
182template <class Value>
184{
185 int m_uid;
186
187public:
189 {
190 }
191
192 int getUid1() const
193 {
194 return m_uid;
195 }
196
197 bool equals(const btHashKey<Value>& other) const
198 {
199 return getUid1() == other.getUid1();
200 }
201 //to our success
202 SIMD_FORCE_INLINE unsigned int getHash() const
203 {
204 unsigned int key = m_uid;
205 // Thomas Wang's hash
206 key += ~(key << 15);
207 key ^= (key >> 10);
208 key += (key << 3);
209 key ^= (key >> 6);
210 key += ~(key << 11);
211 key ^= (key >> 16);
212 return key;
213 }
214};
215
218template <class Key, class Value>
220{
221protected:
224
227
228 void growTables(const Key& /*key*/)
229 {
231
233 {
234 //grow hashtable and next table
236
239
240 int i;
241
242 for (i = 0; i < newCapacity; ++i)
243 {
245 }
246 for (i = 0; i < newCapacity; ++i)
247 {
248 m_next[i] = BT_HASH_NULL;
249 }
250
251 for (i = 0; i < curHashtableSize; i++)
252 {
253 //const Value& value = m_valueArray[i];
254 //const Key& key = m_keyArray[i];
255
256 int hashValue = m_keyArray[i].getHash() & (m_valueArray.capacity() - 1); // New hash value with new mask
259 }
260 }
261 }
262
263public:
264 void insert(const Key& key, const Value& value)
265 {
266 int hash = key.getHash() & (m_valueArray.capacity() - 1);
267
268 //replace value if the key is already there
269 int index = findIndex(key);
270 if (index != BT_HASH_NULL)
271 {
272 m_valueArray[index] = value;
273 return;
274 }
275
276 int count = m_valueArray.size();
278 m_valueArray.push_back(value);
280
283 {
285 //hash with new capacity
286 hash = key.getHash() & (m_valueArray.capacity() - 1);
287 }
288 m_next[count] = m_hashTable[hash];
289 m_hashTable[hash] = count;
290 }
291
292 void remove(const Key& key)
293 {
294 int hash = key.getHash() & (m_valueArray.capacity() - 1);
295
296 int pairIndex = findIndex(key);
297
298 if (pairIndex == BT_HASH_NULL)
299 {
300 return;
301 }
302
303 // Remove the pair from the hash table.
304 int index = m_hashTable[hash];
305 btAssert(index != BT_HASH_NULL);
306
307 int previous = BT_HASH_NULL;
308 while (index != pairIndex)
309 {
310 previous = index;
311 index = m_next[index];
312 }
313
314 if (previous != BT_HASH_NULL)
315 {
316 btAssert(m_next[previous] == pairIndex);
317 m_next[previous] = m_next[pairIndex];
318 }
319 else
320 {
322 }
323
324 // We now move the last pair into spot of the
325 // pair being removed. We need to fix the hash
326 // table indices to support the move.
327
328 int lastPairIndex = m_valueArray.size() - 1;
329
330 // If the removed pair is the last pair, we are done.
332 {
335 return;
336 }
337
338 // Remove the last pair from the hash table.
339 int lastHash = m_keyArray[lastPairIndex].getHash() & (m_valueArray.capacity() - 1);
340
341 index = m_hashTable[lastHash];
342 btAssert(index != BT_HASH_NULL);
343
344 previous = BT_HASH_NULL;
345 while (index != lastPairIndex)
346 {
347 previous = index;
348 index = m_next[index];
349 }
350
351 if (previous != BT_HASH_NULL)
352 {
353 btAssert(m_next[previous] == lastPairIndex);
354 m_next[previous] = m_next[lastPairIndex];
355 }
356 else
357 {
359 }
360
361 // Copy the last pair into the remove pair's spot.
364
365 // Insert the last pair into the hash table
368
371 }
372
373 int size() const
374 {
375 return m_valueArray.size();
376 }
377
378 const Value* getAtIndex(int index) const
379 {
380 btAssert(index < m_valueArray.size());
381 btAssert(index >= 0);
382 if (index >= 0 && index < m_valueArray.size())
383 {
384 return &m_valueArray[index];
385 }
386 return 0;
387 }
388
389 Value* getAtIndex(int index)
390 {
391 btAssert(index < m_valueArray.size());
392 btAssert(index >= 0);
393 if (index >= 0 && index < m_valueArray.size())
394 {
395 return &m_valueArray[index];
396 }
397 return 0;
398 }
399
401 {
402 btAssert(index < m_keyArray.size());
403 btAssert(index >= 0);
404 return m_keyArray[index];
405 }
406
407 const Key getKeyAtIndex(int index) const
408 {
409 btAssert(index < m_keyArray.size());
410 btAssert(index >= 0);
411 return m_keyArray[index];
412 }
413
415 {
416 return find(key);
417 }
418
419 const Value* operator[](const Key& key) const
420 {
421 return find(key);
422 }
423
424 const Value* find(const Key& key) const
425 {
426 int index = findIndex(key);
427 if (index == BT_HASH_NULL)
428 {
429 return NULL;
430 }
431 return &m_valueArray[index];
432 }
433
434 Value* find(const Key& key)
435 {
436 int index = findIndex(key);
437 if (index == BT_HASH_NULL)
438 {
439 return NULL;
440 }
441 return &m_valueArray[index];
442 }
443
444 int findIndex(const Key& key) const
445 {
446 unsigned int hash = key.getHash() & (m_valueArray.capacity() - 1);
447
448 if (hash >= (unsigned int)m_hashTable.size())
449 {
450 return BT_HASH_NULL;
451 }
452
453 int index = m_hashTable[hash];
454 while ((index != BT_HASH_NULL) && key.equals(m_keyArray[index]) == false)
455 {
456 index = m_next[index];
457 }
458 return index;
459 }
460
461 void clear()
462 {
464 m_next.clear();
467 }
468};
469
470#endif //BT_HASH_MAP_H
const int BT_HASH_NULL
Definition btHashMap.h:62
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
#define SIMD_FORCE_INLINE
Definition btScalar.h:98
#define btAssert(x)
Definition btScalar.h:153
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0),...
void push_back(const T &_Val)
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
void setUid1(int uid)
Definition btHashMap.h:82
unsigned int getHash() const
Definition btHashMap.h:92
btHashInt(int uid)
Definition btHashMap.h:73
int m_uid
Definition btHashMap.h:66
int getUid1() const
Definition btHashMap.h:77
bool equals(const btHashInt &other) const
Definition btHashMap.h:87
btHashKeyPtr(int uid)
Definition btHashMap.h:153
bool equals(const btHashKeyPtr< Value > &other) const
Definition btHashMap.h:162
int getUid1() const
Definition btHashMap.h:157
unsigned int getHash() const
Definition btHashMap.h:168
unsigned int getHash() const
Definition btHashMap.h:202
btHashKey(int uid)
Definition btHashMap.h:188
bool equals(const btHashKey< Value > &other) const
Definition btHashMap.h:197
int getUid1() const
Definition btHashMap.h:192
The btHashMap template class implements a generic and lightweight hashmap.
Definition btHashMap.h:220
void insert(const Key &key, const Value &value)
Definition btHashMap.h:264
Key getKeyAtIndex(int index)
Definition btHashMap.h:400
void clear()
Definition btHashMap.h:461
int size() const
Definition btHashMap.h:373
void growTables(const Key &)
Definition btHashMap.h:228
Value * operator[](const Key &key)
Definition btHashMap.h:414
int findIndex(const Key &key) const
Definition btHashMap.h:444
const Key getKeyAtIndex(int index) const
Definition btHashMap.h:407
Value * find(const Key &key)
Definition btHashMap.h:434
void remove(const Key &key)
Definition btHashMap.h:292
btAlignedObjectArray< int > m_hashTable
Definition btHashMap.h:222
btAlignedObjectArray< int > m_next
Definition btHashMap.h:223
const Value * getAtIndex(int index) const
Definition btHashMap.h:378
btAlignedObjectArray< Key > m_keyArray
Definition btHashMap.h:226
btAlignedObjectArray< Value > m_valueArray
Definition btHashMap.h:225
const Value * find(const Key &key) const
Definition btHashMap.h:424
Value * getAtIndex(int index)
Definition btHashMap.h:389
const Value * operator[](const Key &key) const
Definition btHashMap.h:419
const void * getPointer() const
Definition btHashMap.h:120
btHashPtr(const void *ptr)
Definition btHashMap.h:115
const void * m_pointer
Definition btHashMap.h:110
bool equals(const btHashPtr &other) const
Definition btHashMap.h:125
unsigned int getHash() const
Definition btHashMap.h:131
unsigned int m_hashValues[2]
Definition btHashMap.h:111
very basic hashable string implementation, compatible with btHashMap
Definition btHashMap.h:24
bool equals(const btHashString &other) const
Definition btHashMap.h:56
std::string m_string1
Definition btHashMap.h:25
unsigned int getHash() const
Definition btHashMap.h:28
btHashString(const char *name)
Definition btHashMap.h:38
unsigned int m_hash
Definition btHashMap.h:26