AGX Dynamics 2.42.1.1
Loading...
Searching...
No Matches
HashFunction.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#ifndef AGX_HASHFUNCTIONS_H
18#define AGX_HASHFUNCTIONS_H
19
20#include <stddef.h>
21#include <cstring>
22#include <ratio>
23
24#include <agx/agx.h>
25#include <agx/Integer.h>
26#include <agx/String.h>
27#include <agx/hash.h>
28
29namespace agx
30{
31
33 // See hash function declarations in agx/hash.h
35
36
37
38
39 // Implementation of basic hash functions
40
41
43 {
44 return (id1 < id2) ? (((UInt64)id1 << 32) | (UInt64)id2) : (((UInt64)id2 << 32) | (UInt64)id1);
45 }
46
47 inline bool hashKeyContains(UInt64 key, UInt32 id)
48 {
49 return (UInt32)key == id || (UInt32)(key >> 32) == id;
50 }
51
52 inline void splitHashKey(UInt64 key, UInt32& id1, UInt32& id2)
53 {
54 id1 = (UInt32)key;
55 id2 = (UInt32)(key >> 32);
56 }
57
68 {
69 x += 0x9e3779b97f4a7c15ULL;
70 x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;
71 x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;
72 x = x ^ (x >> 31);
73 return x;
74 }
75
76 inline UInt64 hash64( UInt64 x, UInt64 y, UInt64 z )
77 {
78 UInt64 h = 0x9e3779b97f4a7c15ULL; // Large odd prime (golden ratio)
79 h = ( h ^ splitMix64( x ) ) * 0xbf58476d1ce4e5b9ULL;
80 h = ( h ^ splitMix64( y ) ) * 0x94d049bb133111ebULL;
81 h = ( h ^ splitMix64( z ) );
82 return h;
83 }
84
85 inline UInt32 hash( UInt64 x, UInt64 y, UInt64 z )
86 {
87 const auto h = hash64( x, y, z );
88 return static_cast<UInt32>( h ^ ( h >> 32 ) );
89 }
90
98 inline UInt64 spatialHash( double x, double eps )
99 {
100 static constexpr double dInt64Max = (double)std::numeric_limits<Int64>::max();
101 static constexpr double dInt64Min = (double)std::numeric_limits<Int64>::min();
102
103 if ( eps < 1.0E-14 ) {
104 UInt64 result{};
105 std::memcpy( &result, &x, sizeof( UInt64 ) );
106 return result;
107 }
108
109 const double t = x / eps;
110 if ( t > dInt64Max )
111 return static_cast<UInt64>( std::numeric_limits<Int64>::max() );
112 else if ( t < dInt64Min )
113 return static_cast<UInt64>( std::numeric_limits<Int64>::min() );
114
115 return static_cast<UInt64>( static_cast<Int64>( std::floor( t ) ) );
116 }
117
118 inline UInt64 spatialHash64( double x, double y, double z, double eps )
119 {
120 return hash64( spatialHash( x, eps ),
121 spatialHash( y, eps ),
122 spatialHash( z, eps ) );
123 }
124
125 inline UInt32 spatialHash( double x, double y, double z, double eps )
126 {
127 return hash( spatialHash( x, eps ),
128 spatialHash( y, eps ),
129 spatialHash( z, eps ) );
130 }
131
135 template<typename Vec3Type, class Epsilon = std::ratio<1, 1'000'000>>
137 {
138 static constexpr double CellSize = (double)Epsilon::num / Epsilon::den;
139
140 inline UInt32 operator()( const Vec3Type& v ) const
141 {
142 return spatialHash( (double)v[ 0 ],
143 (double)v[ 1 ],
144 (double)v[ 2 ],
145 CellSize );
146 }
147 };
148
149 inline UInt32 hash( UInt32 x, UInt32 y, UInt32 z )
150 {
151 const UInt32 p1 = 73856093UL;
152 const UInt32 p2 = 19349663UL;
153 const UInt32 p3 = 83492791UL;
154
155 return (p1 * x) ^ (p2 * y) ^ (p3 * z);
156 }
157
158 template<typename T>
159 UInt32 HashFn<T>::operator()(const T& key) const
160 {
161 return key.hash();
162 }
163
164 template<typename T>
165 inline UInt32 hash(const T& key)
166 {
167 HashFn<T> hashFn;
168 return hashFn(key);
169 }
170
171 inline UInt32 hash( UInt32 h1, UInt32 h2 )
172 {
173 return h1 ^ (h2 + 0x9e3779b9 + (h1<<6) + (h1>>2));
174 }
175
176 template<typename T1, typename T2>
177 inline bool hashKeyEqual(const T1& key1, const T2& key2)
178 {
179 return key1 == key2;
180 }
181
182 // Pair hashing
183 template<typename T1, typename T2>
184 struct HashFn< std::pair<T1, T2> >
185 {
186 inline UInt32 operator()(const std::pair<T1,T2>& key) const
187 {
188 return hash(hash(key.first), hash(key.second));
189 }
190 };
191
192 // Integer hash functions
193 template<>
195 {
196 inline UInt32 operator()(UInt32 key) const
197 {
198 /* http://www.concentric.net/~Ttwang/tech/inthash.htm */
199 key = ~key + (key << 15); // key = (key << 15) - key - 1;
200 key = key ^ (key >> 12);
201 key = key + (key << 2);
202 key = key ^ (key >> 4);
203 key = key * 2057; // key = (key + (key << 3)) + (key << 11);
204 key = key ^ (key >> 16);
205 return key;
206 }
207 };
208
209 template<>
210 struct HashFn<Int32>
211 {
212 inline UInt32 operator()(Int32 key) const
213 {
214 return hash((UInt32)key);
215 }
216 };
217
218 template<>
220 {
221 inline UInt32 operator()(UInt64 key) const
222 {
223 /* http://www.concentric.net/~Ttwang/tech/inthash.htm */
224 key = (~key) + (key << 18); // key = (key << 18) - key - 1;
225 key = key ^ (key >> 31);
226 key = key * 21; // key = (key + (key << 2)) + (key << 4);
227 key = key ^ (key >> 11);
228 key = key + (key << 6);
229 key = key ^ (key >> 22);
230 return (UInt32)key;
231 }
232 };
233
234 template<>
235 struct HashFn<Int64>
236 {
237 inline UInt32 operator()(Int64 key) const
238 {
239 return hash((UInt64)key);
240 }
241
242 };
243
244#ifdef __APPLE__
245 template<>
246 struct HashFn<size_t>
247 {
248 inline UInt32 operator()(size_t key) const
249 {
250 return hash((UInt64)(key));
251 }
252
253 };
254#endif
255
256 // Pointer hashing
257
258 template<typename T>
259 struct HashFn<T*>
260 {
261 typedef const T* PtrT;
262
263 inline UInt32 operator()(const PtrT key) const
264 {
265 return hash((UInt64)(key));
266 }
267 };
268
269 // String hashing
270
271 // Hash functions
272
273 template<typename T>
274 inline UInt32 stringHash(const T& key, UInt32 startValue = 0)
275 {
276 UInt32 hashValue = startValue;
277
278 for (UInt32 i = 0; i < key.length(); i++)
279 hashValue = 37 * hashValue + (UInt32)key[i];
280
281 return hashValue;
282 }
283
284 template<>
285 struct HashFn<std::string>
286 {
287 inline UInt32 operator()(const std::string& key) const
288 {
289 return agx::stringHash(key);
290 }
291 };
292
293 template<>
295 {
296 inline UInt32 operator()(const String& key) const
297 {
298 return agx::stringHash(key);
299 }
300 };
301
302 template<>
303 struct HashFn<const char *>
304 {
305 inline UInt32 operator()(const char *key) const
306 {
307 UInt32 hashValue = 0;
308
309 while (*key)
310 hashValue = 37 * hashValue + (UInt32)(*key++);
311
312 return hashValue;
313 }
314 };
315
316 inline bool hashKeyEqual(char *key1, char *key2)
317 {
318 return strcmp(key1, key2) == 0;
319 }
320
321 inline bool hashKeyEqual(const char *key1, const char *key2)
322 {
323 return strcmp(key1, key2) == 0;
324 }
325}
326
327#endif /* _AGX_HASHFUNCTIONS_H_ */
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
UInt32 hash(const T &key)
Definition: HashFunction.h:165
UInt32 stringHash(const T &key, UInt32 startValue=0)
Definition: HashFunction.h:274
int32_t Int32
Definition: Integer.h:37
AGXCORE_EXPORT void splitHashKey(agx::UInt64 key, agx::UInt32 &id1, agx::UInt32 &id2)
Definition: HashFunction.h:52
uint32_t UInt32
Definition: Integer.h:32
UInt64 splitMix64(UInt64 x)
SplitMix64 pulls entropy from the high 32 bits to the low, which preserves more uniqueness performing...
Definition: HashFunction.h:67
uint64_t UInt64
Definition: Integer.h:33
int64_t Int64
Definition: Integer.h:38
AGXCORE_EXPORT agx::UInt64 buildHashKey(agx::UInt32 id1, agx::UInt32 id2)
Definition: HashFunction.h:42
UInt64 hash64(UInt64 x, UInt64 y, UInt64 z)
Definition: HashFunction.h:76
UInt64 spatialHash(double x, double eps)
Hash function suitable for spatial hashing with configurable grid spacing eps.
Definition: HashFunction.h:98
bool hashKeyEqual(const T1 &key1, const T2 &key2)
Definition: HashFunction.h:177
UInt64 spatialHash64(double x, double y, double z, double eps)
Definition: HashFunction.h:118
AGXCORE_EXPORT bool hashKeyContains(agx::UInt64 key, agx::UInt32 id)
Definition: HashFunction.h:47
STL namespace.
UInt32 operator()(Int32 key) const
Definition: HashFunction.h:212
UInt32 operator()(Int64 key) const
Definition: HashFunction.h:237
UInt32 operator()(const String &key) const
Definition: HashFunction.h:296
UInt32 operator()(const PtrT key) const
Definition: HashFunction.h:263
UInt32 operator()(UInt32 key) const
Definition: HashFunction.h:196
UInt32 operator()(UInt64 key) const
Definition: HashFunction.h:221
UInt32 operator()(const char *key) const
Definition: HashFunction.h:305
UInt32 operator()(const std::pair< T1, T2 > &key) const
Definition: HashFunction.h:186
UInt32 operator()(const std::string &key) const
Definition: HashFunction.h:287
UInt32 operator()(const T &key) const
Definition: HashFunction.h:159
Spatial hashing of 3D vector types with default grid size 1.0E-6.
Definition: HashFunction.h:137
UInt32 operator()(const Vec3Type &v) const
Definition: HashFunction.h:140
static constexpr double CellSize
Definition: HashFunction.h:138