Atoms Crowd  7.0.0
Hash.impl.h
1 // ===========================================================================
2 // Copyright (c) 2015 Toolchefs Ltd. All rights reserved.
3 //
4 // Use of this software is subject to the terms of the Toolchefs license
5 // agreement provided at the time of installation or download, or which
6 // otherwise accompanies this software in either electronic or hard copy form.
7 // ===========================================================================
8 
9 //-----------------------------------------------------------------------------
10 // MurmurHash3 was written by Austin Appleby, and is placed in the public
11 // domain. The author hereby disclaims copyright to this source code.
12 // Code from https://github.com/aappleby/smhasher
13 
14 namespace AtomsCore
15 {
16 //-----------------------------------------------------------------------------
17 // Platform-specific functions and macros
18 // Microsoft Visual Studio
19 #if defined(_MSC_VER)
20 #define FORCE_INLINE __forceinline
21 #include <stdlib.h>
22 #define ROTL32(x,y) _rotl(x,y)
23 #define ROTL64(x,y) _rotl64(x,y)
24 #define BIG_CONSTANT(x) (x)
25 // Other compilers
26 #else // defined(_MSC_VER)
27 #define FORCE_INLINE inline __attribute__((always_inline))
28 
29  inline uint32_t rotl32(uint32_t x, int8_t r)
30  {
31  return (x << r) | (x >> (32 - r));
32  }
33 
34  inline uint64_t rotl64(uint64_t x, int8_t r)
35  {
36  return (x << r) | (x >> (64 - r));
37  }
38 
39 #define ROTL32(x,y) rotl32(x,y)
40 #define ROTL64(x,y) rotl64(x,y)
41 
42 #define BIG_CONSTANT(x) (x##LLU)
43 #endif // !defined(_MSC_VER)
44 
45  //-----------------------------------------------------------------------------
46  // Block read - if your platform needs to do endian-swapping or can only
47  // handle aligned reads, do the conversion here
48 
49 
50  FORCE_INLINE uint32_t getblock32(const uint32_t * p, size_t i)
51  {
52  return p[i];
53  }
54 
55  FORCE_INLINE uint64_t getblock64(const uint64_t * p, size_t i)
56  {
57  return p[i];
58  }
59 
60  //-----------------------------------------------------------------------------
61  // Finalization mix - force all bits of a hash block to avalanche
62 
63  FORCE_INLINE uint32_t fmix32(uint32_t h)
64  {
65  h ^= h >> 16;
66  h *= 0x85ebca6b;
67  h ^= h >> 13;
68  h *= 0xc2b2ae35;
69  h ^= h >> 16;
70  return h;
71  }
72 
73  //----------
74  FORCE_INLINE uint64_t fmix64(uint64_t k)
75  {
76  k ^= k >> 33;
77  k *= BIG_CONSTANT(0xff51afd7ed558ccd);
78  k ^= k >> 33;
79  k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
80  k ^= k >> 33;
81  return k;
82  }
83 
84 
85  const MurmurHash3 &MurmurHash3::operator = (const MurmurHash3 &other)
86  {
87  seed[0] = other.seed[0];
88  seed[1] = other.seed[1];
89  return *this;
90  }
91 
92  bool MurmurHash3::operator==(const MurmurHash3 &rh) const
93  {
94  return seed[0] == rh.seed[0] && seed[1] == rh.seed[1];
95  }
96 
97  bool MurmurHash3::operator!=(const MurmurHash3 &rh) const
98  {
99  return seed[0] != rh.seed[0] || seed[1] != rh.seed[1];
100  }
101 
102  bool MurmurHash3::operator<(const MurmurHash3 &rh) const
103  {
104  return seed[0] < rh.seed[0] || (seed[0] == rh.seed[0] && seed[1] < rh.seed[1]);
105  }
106 
107  void MurmurHash3::hash(const void *key, size_t len)
108  {
109  const uint8_t * data = (const uint8_t*)key;
110  const size_t nblocks = len / 16;
111 
112  uint64_t h1 = seed[0];
113  uint64_t h2 = seed[1];
114 
115  const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
116  const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
117 
118  //----------
119  // body
120  const uint64_t * blocks = (const uint64_t *)(data);
121 
122  for (size_t i = 0; i < nblocks; i++)
123  {
124  uint64_t k1 = getblock64(blocks, i * 2 + 0);
125  uint64_t k2 = getblock64(blocks, i * 2 + 1);
126  k1 *= c1; k1 = ROTL64(k1, 31); k1 *= c2; h1 ^= k1;
127  h1 = ROTL64(h1, 27); h1 += h2; h1 = h1 * 5 + 0x52dce729;
128  k2 *= c2; k2 = ROTL64(k2, 33); k2 *= c1; h2 ^= k2;
129  h2 = ROTL64(h2, 31); h2 += h1; h2 = h2 * 5 + 0x38495ab5;
130  }
131 
132  //----------
133  // tail
134 
135  const uint8_t * tail = (const uint8_t*)(data + nblocks * 16);
136 
137  uint64_t k1 = 0;
138  uint64_t k2 = 0;
139 
140  switch (len & 15)
141  {
142  case 15: k2 ^= ((uint64_t)tail[14]) << 48;
143  case 14: k2 ^= ((uint64_t)tail[13]) << 40;
144  case 13: k2 ^= ((uint64_t)tail[12]) << 32;
145  case 12: k2 ^= ((uint64_t)tail[11]) << 24;
146  case 11: k2 ^= ((uint64_t)tail[10]) << 16;
147  case 10: k2 ^= ((uint64_t)tail[9]) << 8;
148  case 9: k2 ^= ((uint64_t)tail[8]) << 0;
149  k2 *= c2; k2 = ROTL64(k2, 33); k2 *= c1; h2 ^= k2;
150  case 8: k1 ^= ((uint64_t)tail[7]) << 56;
151  case 7: k1 ^= ((uint64_t)tail[6]) << 48;
152  case 6: k1 ^= ((uint64_t)tail[5]) << 40;
153  case 5: k1 ^= ((uint64_t)tail[4]) << 32;
154  case 4: k1 ^= ((uint64_t)tail[3]) << 24;
155  case 3: k1 ^= ((uint64_t)tail[2]) << 16;
156  case 2: k1 ^= ((uint64_t)tail[1]) << 8;
157  case 1: k1 ^= ((uint64_t)tail[0]) << 0;
158  k1 *= c1; k1 = ROTL64(k1, 31); k1 *= c2; h1 ^= k1;
159  };
160 
161  //----------
162  // finalization
163 
164  h1 ^= len; h2 ^= len;
165  h1 += h2;
166  h2 += h1;
167 
168  h1 = fmix64(h1);
169  h2 = fmix64(h2);
170 
171  h1 += h2;
172  h2 += h1;
173 
174  ((uint64_t*)seed)[0] = h1;
175  ((uint64_t*)seed)[1] = h2;
176  }
177 
178  void MurmurHash3::append(bool data)
179  {
180  char value = data;
181  hash(&value, sizeof(char));
182  }
183 
184  void MurmurHash3::append(char data)
185  {
186  hash(&data, sizeof(char));
187  }
188 
189  void MurmurHash3::append(unsigned char data)
190  {
191  hash(&data, sizeof(unsigned char));
192  }
193 
194  void MurmurHash3::append(short data)
195  {
196  hash(&data, sizeof(short));
197  }
198 
199  void MurmurHash3::append(unsigned short data)
200  {
201  hash(&data, sizeof(unsigned short));
202  }
203 
204  void MurmurHash3::append(int data)
205  {
206  hash(&data, sizeof(int));
207  }
208 
209  void MurmurHash3::append(unsigned int data)
210  {
211  hash(&data, sizeof(unsigned int));
212  }
213 
214  void MurmurHash3::append(int64_t data)
215  {
216  hash(&data, sizeof(int64_t));
217  }
218 
219  void MurmurHash3::append(uint64_t data)
220  {
221  hash(&data, sizeof(uint64_t));
222  }
223 #ifdef __APPLE__
224  void MurmurHash3::append(size_t data)
225  {
226  hash(&data, sizeof(uint64_t));
227  }
228 #endif
229  void MurmurHash3::append(float data)
230  {
231  hash(&data, sizeof(float));
232  }
233 
234  void MurmurHash3::append(double data)
235  {
236  hash(&data, sizeof(double));
237  }
238 
239  void MurmurHash3::append(const char *data)
240  {
241  hash(&data, sizeof(char) * strlen(data));
242  }
243 
244  void MurmurHash3::append(const std::string &data)
245  {
246  hash(&data[0], sizeof(char) * data.size());
247  }
248 
249  void MurmurHash3::append(const Vector2 &data)
250  {
251  hash(&data.getValue()[0], sizeof(double) * 2);
252  }
253 
254  void MurmurHash3::append(const Vector2f &data)
255  {
256  hash(&data.getValue()[0], sizeof(float) * 2);
257  }
258 
259  void MurmurHash3::append(const Vector2i &data)
260  {
261  hash(&data.getValue()[0], sizeof(int) * 2);
262  }
263 
264  void MurmurHash3::append(const Vector3 &data)
265  {
266  hash(&data.getValue()[0], sizeof(double) * 2);
267  }
268 
269  void MurmurHash3::append(const Vector3f &data)
270  {
271  hash(&data.getValue()[0], sizeof(float) * 3);
272  }
273 
274  void MurmurHash3::append(const Vector3i &data)
275  {
276  hash(&data.getValue()[0], sizeof(int) * 3);
277  }
278 
279  void MurmurHash3::append(const Vector4 &data)
280  {
281  append(data.x); append(data.y); append(data.z); append(data.w);
282  }
283 
284  void MurmurHash3::append(const Vector4f &data)
285  {
286  append(data.x); append(data.y); append(data.z); append(data.w);
287  }
288 
289  void MurmurHash3::append(const Vector4i &data)
290  {
291  append(data.x); append(data.y); append(data.z); append(data.w);
292  }
293 
294  void MurmurHash3::append(const Euler &data)
295  {
296  hash(&data.getValue()[0], sizeof(double));
297  }
298 
299  void MurmurHash3::append(const Eulerf &data)
300  {
301  hash(&data.getValue()[0], sizeof(float));
302  }
303 
304  void MurmurHash3::append(const Quaternion &data)
305  {
306  append(data.r); append(data.v);
307  }
308 
309  void MurmurHash3::append(const Quaternionf &data)
310  {
311  append(data.r); append(data.v);
312  }
313 
314  void MurmurHash3::append(const Box2 &data)
315  {
316  append(data.min); append(data.max);
317  }
318 
319  void MurmurHash3::append(const Box2i &data)
320  {
321  append(data.min); append(data.max);
322  }
323 
324  void MurmurHash3::append(const Box2f &data)
325  {
326  append(data.min); append(data.max);
327  }
328 
329  void MurmurHash3::append(const Box3 &data)
330  {
331  append(data.min); append(data.max);
332  }
333 
334  void MurmurHash3::append(const Box3i &data)
335  {
336  append(data.min); append(data.max);
337  }
338 
339  void MurmurHash3::append(const Box3f &data)
340  {
341  append(data.min); append(data.max);
342  }
343 
344  void MurmurHash3::append(const Matrix &data)
345  {
346  hash(&data.getValue()[0], sizeof(double) * 16);
347  }
348 
349  void MurmurHash3::append(const Matrixf &data)
350  {
351  hash(&data.getValue()[0], sizeof(float) * 16);
352  }
353 
355  // Vectors
357 
358  void MurmurHash3::append(const std::vector<bool>& data)
359  {
360  for (size_t i = 0; i < data.size(); ++i)
361  {
362  append(data[i]);
363  }
364  }
365 
366  void MurmurHash3::append(const std::vector<char>& data)
367  {
368  hash(&data[0], sizeof(char) * data.size());
369  }
370 
371  void MurmurHash3::append(const std::vector<unsigned char>& data)
372  {
373  hash(&data[0], sizeof(unsigned char) * data.size());
374  }
375 
376  void MurmurHash3::append(const std::vector<short>& data)
377  {
378  hash(&data[0], sizeof(short) * data.size());
379  }
380 
381  void MurmurHash3::append(const std::vector<unsigned short>& data)
382  {
383  hash(&data[0], sizeof(unsigned short) * data.size());
384  }
385 
386  void MurmurHash3::append(const std::vector<int>& data)
387  {
388  hash(&data[0], sizeof(int) * data.size());
389  }
390 
391  void MurmurHash3::append(const std::vector<unsigned int>& data)
392  {
393  hash(&data[0], sizeof(unsigned int) * data.size());
394  }
395 
396  void MurmurHash3::append(const std::vector<int64_t>& data)
397  {
398  hash(&data[0], sizeof(int64_t) * data.size());
399  }
400 
401  void MurmurHash3::append(const std::vector<uint64_t>& data)
402  {
403  hash(&data[0], sizeof(uint64_t) * data.size());
404  }
405 
406  void MurmurHash3::append(const std::vector<float>& data)
407  {
408  hash(&data[0], sizeof(float) * data.size());
409  }
410 
411  void MurmurHash3::append(const std::vector<double>& data)
412  {
413  hash(&data[0], sizeof(double) * data.size());
414  }
415 
416  void MurmurHash3::append(const std::vector<std::string> &data)
417  {
418  for (size_t i = 0; i < data.size(); ++i)
419  {
420  append(data[i]);
421  }
422  }
423 
424  void MurmurHash3::append(const std::vector<Vector2> &data)
425  {
426  hash(&data[0], sizeof(Vector2) * data.size());
427  }
428 
429  void MurmurHash3::append(const std::vector<Vector2f> &data)
430  {
431  hash(&data[0], sizeof(Vector2f) * data.size());
432  }
433 
434  void MurmurHash3::append(const std::vector<Vector2i> &data)
435  {
436  hash(&data[0], sizeof(Vector2i) * data.size());
437  }
438 
439  void MurmurHash3::append(const std::vector<Vector3> &data)
440  {
441  hash(&data[0], sizeof(Vector3) * data.size());
442  }
443 
444  void MurmurHash3::append(const std::vector<Vector3f> &data)
445  {
446  hash(&data[0], sizeof(Vector3f) * data.size());
447  }
448 
449  void MurmurHash3::append(const std::vector<Vector3i> &data)
450  {
451  hash(&data[0], sizeof(Vector3i) * data.size());
452  }
453 
454  void MurmurHash3::append(const std::vector<Vector4> &data)
455  {
456  hash(&data[0], sizeof(Vector4) * data.size());
457  }
458 
459  void MurmurHash3::append(const std::vector<Vector4f> &data)
460  {
461  hash(&data[0], sizeof(Vector4f) * data.size());
462  }
463 
464  void MurmurHash3::append(const std::vector<Vector4i> &data)
465  {
466  hash(&data[0], sizeof(Vector4i) * data.size());
467  }
468 
469  void MurmurHash3::append(const std::vector<Euler> &data)
470  {
471  hash(&data[0], sizeof(Euler) * data.size());
472  }
473 
474  void MurmurHash3::append(const std::vector<Eulerf> &data)
475  {
476  hash(&data[0], sizeof(Eulerf) * data.size());
477  }
478 
479  void MurmurHash3::append(const std::vector<Quaternion> &data)
480  {
481  hash(&data[0], sizeof(Quaternion) * data.size());
482  }
483 
484  void MurmurHash3::append(const std::vector<Quaternionf> &data)
485  {
486  hash(&data[0], sizeof(Quaternionf) * data.size());
487  }
488 
489  void MurmurHash3::append(const std::vector<Box2> &data)
490  {
491  hash(&data[0], sizeof(Box2) * data.size());
492  }
493 
494  void MurmurHash3::append(const std::vector<Box2i> &data)
495  {
496  hash(&data[0], sizeof(Box2i) * data.size());
497  }
498 
499  void MurmurHash3::append(const std::vector<Box2f> &data)
500  {
501  hash(&data[0], sizeof(Box2f) * data.size());
502  }
503 
504  void MurmurHash3::append(const std::vector<Box3> &data)
505  {
506  hash(&data[0], sizeof(Box3) * data.size());
507  }
508 
509  void MurmurHash3::append(const std::vector<Box3i> &data)
510  {
511  hash(&data[0], sizeof(Box3i) * data.size());
512  }
513 
514  void MurmurHash3::append(const std::vector<Box3f> &data)
515  {
516  hash(&data[0], sizeof(Box3f) * data.size());
517  }
518 
519  void MurmurHash3::append(const std::vector<Matrix> &data)
520  {
521  hash(&data[0], sizeof(Matrix) * data.size());
522  }
523 
524  void MurmurHash3::append(const std::vector<Matrixf> &data)
525  {
526  hash(&data[0], sizeof(Matrixf) * data.size());
527  }
528 
529  void MurmurHash3::append(const MurmurHash3& data)
530  {
531  hash(&data.seed[0], sizeof(size_t) * 2);
532  }
533 }
Definition: ImathBox.h:36
V min
The minimum value of the box.
Definition: ImathBox.h:43
V max
The maximum value of the box.
Definition: ImathBox.h:46
Definition: ImathEuler.h:118
ATOMSMATH_HOSTDEVICE void getValue(S &a, S &b, S &c) const noexcept
Return the value in a, b, and c
AtomsCore namespace.
Definition: Agent.h:344
AtomsMath::Vector4f Vector4f
Vector4 class.
Definition: AtomsMath.h:61
AtomsMath::Vector3i Vector3i
Vector3i class.
Definition: AtomsMath.h:59
AtomsMath::Vector2 Vector2
Vector2 class.
Definition: AtomsMath.h:54
AtomsMath::Vector4i Vector4i
Vector4 class.
Definition: AtomsMath.h:62
AtomsMath::Quaternion Quaternion
Quaternion class.
Definition: AtomsMath.h:67
AtomsMath::Vector2i Vector2i
Vector2 class.
Definition: AtomsMath.h:56
AtomsMath::Vector4 Vector4
Vector4 class.
Definition: AtomsMath.h:60
AtomsMath::Box3 Box3
Bounding box class.
Definition: AtomsMath.h:74
AtomsMath::Box2 Box2
Bounding box class.
Definition: AtomsMath.h:71
AtomsMath::Matrixf Matrixf
Matrix class.
Definition: AtomsMath.h:64
AtomsMath::Vector2f Vector2f
Vector2 class.
Definition: AtomsMath.h:55
AtomsMath::Vector3 Vector3
Vector3 class.
Definition: AtomsMath.h:57
AtomsMath::Matrix Matrix
Matrix class.
Definition: AtomsMath.h:63
AtomsMath::Vector3f Vector3f
Vector3 class.
Definition: AtomsMath.h:58
AtomsMath::Quaternionf Quaternionf
Quaternion class.
Definition: AtomsMath.h:68