36 #define NAMESPACE_FOR_HASH_FUNCTIONS OIIO::farmhash
40 #pragma warning( disable : 4319 )
49 #ifdef FARMHASH_ASSUME_SSSE3
50 #undef FARMHASH_ASSUME_SSSE3
51 #define FARMHASH_ASSUME_SSSE3 1
54 #ifdef FARMHASH_ASSUME_SSE41
55 #undef FARMHASH_ASSUME_SSE41
56 #define FARMHASH_ASSUME_SSE41 1
59 #ifdef FARMHASH_ASSUME_SSE42
60 #undef FARMHASH_ASSUME_SSE42
61 #define FARMHASH_ASSUME_SSE42 1
64 #ifdef FARMHASH_ASSUME_AESNI
65 #undef FARMHASH_ASSUME_AESNI
66 #define FARMHASH_ASSUME_AESNI 1
69 #ifdef FARMHASH_ASSUME_AVX
70 #undef FARMHASH_ASSUME_AVX
71 #define FARMHASH_ASSUME_AVX 1
74 #if !defined(FARMHASH_CAN_USE_CXX11) && defined(LANG_CXX11)
75 #define FARMHASH_CAN_USE_CXX11 1
77 #undef FARMHASH_CAN_USE_CXX11
78 #define FARMHASH_CAN_USE_CXX11 0
86 #if OIIO_CPLUSPLUS_VERSION >= 14
87 # define HASH_CAN_USE_CONSTEXPR 1
89 #define STATIC_INLINE OIIO_HOSTDEVICE inline OIIO_CONSTEXPR14
93 #ifndef FARMHASH_DIE_IF_MISCONFIGURED
94 #ifdef HASH_CAN_USE_CONSTEXPR
95 #define FARMHASH_DIE_IF_MISCONFIGURED
97 #define FARMHASH_DIE_IF_MISCONFIGURED do { *(char*)(len % 17) = 0; } while (0)
103 #ifdef WORDS_BIGENDIAN
104 #undef FARMHASH_BIG_ENDIAN
105 #define FARMHASH_BIG_ENDIAN 1
108 #if defined(FARMHASH_LITTLE_ENDIAN) && defined(FARMHASH_BIG_ENDIAN)
112 #if !defined(FARMHASH_LITTLE_ENDIAN) && !defined(FARMHASH_BIG_ENDIAN)
113 #define FARMHASH_UNKNOWN_ENDIAN 1
116 #if !defined(bswap_32) || !defined(bswap_64)
120 #if defined(HAVE_BUILTIN_BSWAP) || defined(__clang__) || \
121 (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || \
124 #define bswap_32(x) __builtin_bswap32(x)
125 #define bswap_64(x) __builtin_bswap64(x)
130 #if defined(FARMHASH_UNKNOWN_ENDIAN) || !defined(bswap_64)
136 #define bswap_32(x) _byteswap_ulong(x)
137 #define bswap_64(x) _byteswap_uint64(x)
139 #elif defined(__APPLE__)
142 #include <libkern/OSByteOrder.h>
145 #define bswap_32(x) OSSwapInt32(x)
146 #define bswap_64(x) OSSwapInt64(x)
148 #elif defined(__sun) || defined(sun)
150 #include <sys/byteorder.h>
153 #define bswap_32(x) BSWAP_32(x)
154 #define bswap_64(x) BSWAP_64(x)
156 #elif defined(__FreeBSD__)
158 #include <sys/endian.h>
161 #define bswap_32(x) bswap32(x)
162 #define bswap_64(x) bswap64(x)
164 #elif defined(__OpenBSD__)
166 #include <sys/types.h>
169 #define bswap_32(x) swap32(x)
170 #define bswap_64(x) swap64(x)
172 #elif defined(__NetBSD__)
174 #include <sys/types.h>
175 #include <machine/bswap.h>
176 #if defined(__BSWAP_RENAME) && !defined(__bswap_32)
179 #define bswap_32(x) bswap32(x)
180 #define bswap_64(x) bswap64(x)
187 #include <byteswap.h>
191 #ifdef WORDS_BIGENDIAN
192 #define FARMHASH_BIG_ENDIAN 1
198 #ifdef FARMHASH_BIG_ENDIAN
199 #define uint32_in_expected_order(x) (bswap_32(x))
200 #define uint64_in_expected_order(x) (bswap_64(x))
202 #define uint32_in_expected_order(x) (x)
203 #define uint64_in_expected_order(x) (x)
206 #if !defined(FARMHASH_UINT128_T_DEFINED)
207 #define uint128_t OIIO::farmhash::uint128_t
211 template <
typename T>
218 #define Uint128 OIIO::farmhash::Uint128
219 #define CopyUint128 OIIO::farmhash::CopyUint128
220 #define Uint128Low64 OIIO::farmhash::Uint128Low64
221 #define Uint128High64 OIIO::farmhash::Uint128High64
222 #define Hash128to64 OIIO::farmhash::Hash128to64
231 #if !defined(HASH_CAN_USE_CONSTEXPR) || HASH_CAN_USE_CONSTEXPR == 0
235 memcpy(&result, p,
sizeof(result));
241 memcpy(&result, p,
sizeof(result));
247 #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
250 struct BlockOfBytes {
253 BlockOfBytes bob{p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]};
257 struct BlockOfBytes {
260 BlockOfBytes bob{p[0],p[1],p[2],p[3]};
282 (uint64_t(b1) << 8) |
283 (uint64_t(b2) << 16) |
284 (uint64_t(b3) << 24) |
285 (uint64_t(b4) << 32) |
286 (uint64_t(b5) << 40) |
287 (uint64_t(b6) << 48) |
290 (uint64_t(b0) << 56) |
291 (uint64_t(b1) << 48) |
292 (uint64_t(b2) << 40) |
293 (uint64_t(b3) << 32) |
294 (uint64_t(b4) << 24) |
295 (uint64_t(b5) << 16) |
296 (uint64_t(b6) << 8) |
307 (uint32_t(b1) << 8) |
308 (uint32_t(b2) << 16) |
311 (uint32_t(b0) << 24) |
312 (uint32_t(b1) << 16) |
313 (uint32_t(b2) << 8) |
322 const int S =
sizeof(
T);
326 for (
int i = 0; i < S/2; i++) {
327 int hi = 8 * (7 - i);
329 int shift = 8 * (S - (2*i + 1));
330 T lo_mask = mask << lo;
331 T hi_mask = mask << hi;
332 T new_lo = (v & hi_mask) >> shift;
333 T new_hi = (v & lo_mask) << shift;
334 result |= (new_lo | new_hi);
341 #define bswap_32(x) bswap<uint32_t>(x)
342 #define bswap_64(x) bswap<uint64_t>(x)
353 return shift == 0 ? val : ((val >> shift) | (val << (32 - shift)));
358 return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
361 #if defined(_MSC_VER) && defined(FARMHASH_ROTR)
364 return sizeof(
unsigned long) ==
sizeof(val) ?
370 return sizeof(
unsigned long) ==
sizeof(val) ?
393 #define FARMHASH_DEBUG 0
395 #if !defined(FARMHASH_DEBUG) && (!defined(NDEBUG) || defined(_DEBUG))
396 #define FARMHASH_DEBUG 1
409 #if defined (__x86_64) || defined (__x86_64__)
416 #if defined(__i386__) || defined(__i386) || defined(__X86__)
422 #if !defined(is_64bit)
423 #define is_64bit (x86_64 || (sizeof(void*) == 8))
427 #if defined(__SSSE3__) || defined(FARMHASH_ASSUME_SSSE3)
429 #include <immintrin.h>
430 #define can_use_ssse3 1
434 #define can_use_ssse3 0
438 #if defined(__SSE4_1__) || defined(FARMHASH_ASSUME_SSE41)
440 #include <immintrin.h>
441 #define can_use_sse41 1
445 #define can_use_sse41 0
449 #if defined(__SSE4_2__) || defined(FARMHASH_ASSUME_SSE42)
451 #include <nmmintrin.h>
452 #define can_use_sse42 1
456 #define can_use_sse42 0
460 #if defined(__AES__) || defined(FARMHASH_ASSUME_AESNI)
462 #include <wmmintrin.h>
463 #define can_use_aesni 1
467 #define can_use_aesni 0
471 #if defined(__AVX__) || defined(FARMHASH_ASSUME_AVX)
473 #include <immintrin.h>
474 #define can_use_avx 1
477 #define can_use_avx 0
489 #ifdef HASH_CAN_USE_CONSTEXPR
490 # undef can_use_ssse3
491 # define can_use_ssse3 0
492 # undef can_use_sse41
493 # define can_use_sse41 0
494 # undef can_use_sse42
495 # define can_use_sse42 0
496 # undef can_use_aesni
497 # define can_use_aesni 0
499 # define can_use_avx 0
506 #if !FARMHASH_CAN_USE_CXX11
511 #define PERMUTE3(a, b, c) do { simpleSwap(a, b); simpleSwap(a, c); } while (0)
520 #ifndef __CUDA_ARCH__
521 #if can_use_ssse3 || can_use_sse41 || can_use_sse42 || can_use_aesni || can_use_avx
523 return _mm_loadu_si128(reinterpret_cast<const __m128i*>(s));
529 static const uint64_t k0 = 0xc3a5c85c97cb3127ULL;
530 static const uint64_t k1 = 0xb492b66fbe98f273ULL;
531 static const uint64_t k2 = 0x9ae16a3b2f90404fULL;
534 static const uint32_t c1 = 0xcc9e2d51;
535 static const uint32_t c2 = 0x1b873593;
555 return h * 5 + 0xe6546b64;
560 if (
sizeof(x) == 4) {
585 namespace farmhashna {
587 #define Fetch farmhash::inlined::Fetch64
590 #define Rotate farmhash::inlined::Rotate64
593 #define Bswap farmhash::inlined::Bswap64
596 return val ^ (val >> 47);
605 uint64_t
a = (u ^
v) * mul;
607 uint64_t
b = (v ^
a) * mul;
615 uint64_t
mul = inlined::k2 + len * 2;
616 uint64_t
a =
Fetch(s) + inlined::k2;
617 uint64_t
b =
Fetch(s + len - 8);
618 uint64_t
c =
Rotate(b, 37) * mul +
a;
619 uint64_t d = (
Rotate(a, 25) +
b) * mul;
623 uint64_t
mul = inlined::k2 + len * 2;
629 uint8_t
b = s[len >> 1];
630 uint8_t
c = s[len - 1];
631 uint32_t
y =
static_cast<uint32_t
>(
a) + (static_cast<uint32_t>(b) << 8);
632 uint32_t
z = len + (
static_cast<uint32_t
>(
c) << 2);
633 return ShiftMix(y * inlined::k2 ^ z * inlined::k0) * inlined::k2;
641 uint64_t
mul = inlined::k2 + len * 2;
642 uint64_t
a =
Fetch(s) * inlined::k1;
643 uint64_t
b =
Fetch(s + 8);
645 uint64_t d =
Fetch(s + len - 16) * inlined::k2;
647 a +
Rotate(b + inlined::k2, 18) + c, mul);
653 uint64_t
w, uint64_t
x, uint64_t
y, uint64_t
z, uint64_t
a, uint64_t
b) {
655 b =
Rotate(b + a + z, 21);
660 return make_pair(a + z, b + c);
665 const char*
s, uint64_t
a, uint64_t
b) {
676 uint64_t
mul = inlined::k2 + len * 2;
677 uint64_t
a =
Fetch(s) * inlined::k2;
678 uint64_t
b =
Fetch(s + 8);
680 uint64_t d =
Fetch(s + len - 16) * inlined::k2;
684 uint64_t
f =
Fetch(s + 24);
685 uint64_t
g = (y +
Fetch(s + len - 32)) * mul;
686 uint64_t
h = (z +
Fetch(s + len - 24)) * mul;
688 e +
Rotate(f + a, 18) + g, mul);
692 const uint64_t seed = 81;
699 }
else if (len <= 64) {
706 uint64_t
y = seed * inlined::k1 + 113;
707 uint64_t
z =
ShiftMix(y * inlined::k2 + 113) * inlined::k2;
708 pair<uint64_t, uint64_t> v = make_pair(0, 0);
709 pair<uint64_t, uint64_t>
w = make_pair(0, 0);
710 x = x * inlined::k2 +
Fetch(s);
713 const char*
end = s + ((len - 1) / 64) * 64;
714 const char* last64 = end + ((len - 1) & 63) - 63;
715 assert(s + len - 64 == last64);
717 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) * inlined::k1;
718 y =
Rotate(y + v.second + Fetch(s + 48), 42) * inlined::k1;
720 y += v.first +
Fetch(s + 40);
721 z =
Rotate(z + w.first, 33) * inlined::k1;
727 uint64_t
mul = inlined::k1 + ((z & 0xff) << 1);
730 w.first += ((len - 1) & 63);
733 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) *
mul;
734 y =
Rotate(y + v.second + Fetch(s + 48), 42) *
mul;
736 y += v.first * 9 +
Fetch(s + 40);
755 namespace farmhashuo {
757 #define Fetch inlined::Fetch64
760 #define Rotate inlined::Rotate64
763 uint64_t
a = (x ^
y) * mul;
765 uint64_t
b = (y ^
a) * mul;
770 uint64_t seed0, uint64_t seed1) {
778 uint64_t
y = seed1 * inlined::k2 + 113;
780 pair<uint64_t, uint64_t> v = make_pair(seed0, seed1);
781 pair<uint64_t, uint64_t>
w = make_pair(0, 0);
784 uint64_t
mul = inlined::k2 + (u & 0x82);
787 const char*
end = s + ((len - 1) / 64) * 64;
788 const char* last64 = end + ((len - 1) & 63) - 63;
789 assert(s + len - 64 == last64);
791 uint64_t a0 =
Fetch(s);
792 uint64_t a1 =
Fetch(s + 8);
793 uint64_t a2 =
Fetch(s + 16);
794 uint64_t a3 =
Fetch(s + 24);
795 uint64_t a4 =
Fetch(s + 32);
796 uint64_t a5 =
Fetch(s + 40);
797 uint64_t a6 =
Fetch(s + 48);
798 uint64_t a7 =
Fetch(s + 56);
811 v.first =
Rotate(v.first, 33);
812 v.second =
Rotate(v.second, 30);
835 w.second =
Rotate(w.second, 34);
842 v.second =
Rotate(v.second, 28);
843 v.first =
Rotate(v.first, 20);
844 w.first += ((len - 1) & 63);
850 y += v.first +
Fetch(s + 40);
855 H(v.second + y, w.second + z, inlined::k2, 30) ^ x,
870 namespace farmhashxo {
872 #define Fetch inlined::Fetch64
875 #define Rotate inlined::Rotate64
878 uint64_t seed0 = 0, uint64_t seed1 = 0) {
879 uint64_t
a =
Fetch(s) * inlined::k1;
880 uint64_t
b =
Fetch(s + 8);
882 uint64_t d =
Fetch(s + len - 16) * inlined::k2;
883 uint64_t u =
Rotate(a + b, 43) +
Rotate(c, 30) + d + seed0;
884 uint64_t v = a +
Rotate(b + inlined::k2, 18) + c + seed1;
892 uint64_t mul0 = inlined::k2 - 30;
893 uint64_t mul1 = inlined::k2 - 30 + 2 * len;
894 uint64_t h0 =
H32(s, 32, mul0);
895 uint64_t h1 =
H32(s + len - 32, 32, mul1);
896 return ((h1 * mul1) + h0) * mul1;
901 uint64_t mul0 = inlined::k2 - 114;
902 uint64_t mul1 = inlined::k2 - 114 + 2 * len;
903 uint64_t h0 =
H32(s, 32, mul0);
904 uint64_t h1 =
H32(s + 32, 32, mul1);
905 uint64_t h2 =
H32(s + len - 32, 32, mul1, h0, h1);
906 return (h2 * 9 + (h0 >> 17) + (h1 >> 21)) * mul1;
916 }
else if (len <= 64) {
918 }
else if (len <= 96) {
920 }
else if (len <= 256) {
935 namespace farmhashte {
936 #if !can_use_sse41 || !x86_64
940 return s == NULL ? 0 : len;
945 return seed +
Hash64(s, len);
949 uint64_t seed0, uint64_t seed1) {
951 return seed0 + seed1 +
Hash64(s, len);
957 #define Fetch inlined::Fetch64
960 #define Rotate inlined::Rotate64
963 #define Bswap inlined::Bswap64
967 STATIC_INLINE __m128i Xor(__m128i
x, __m128i
y) {
return _mm_xor_si128(x, y); }
968 STATIC_INLINE __m128i Mul(__m128i
x, __m128i
y) {
return _mm_mullo_epi32(x, y); }
969 STATIC_INLINE __m128i Shuf(__m128i
x, __m128i
y) {
return _mm_shuffle_epi8(y, x); }
974 uint64_t seed0, uint64_t seed1) {
975 const __m128i kShuf =
976 _mm_set_epi8(4, 11, 10, 5, 8, 15, 6, 9, 12, 2, 14, 13, 0, 7, 3, 1);
977 const __m128i kMult =
978 _mm_set_epi8(0xbd, 0xd6, 0x33, 0x39, 0x45, 0x54, 0xfa, 0x03,
979 0x34, 0x3e, 0x33, 0xed, 0xcc, 0x9e, 0x2d, 0x51);
980 uint64_t seed2 = (seed0 + 113) * (seed1 + 9);
981 uint64_t seed3 = (
Rotate(seed0, 23) + 27) * (
Rotate(seed1, 30) + 111);
982 __m128i d0 = _mm_cvtsi64_si128(seed0);
983 __m128i d1 = _mm_cvtsi64_si128(seed1);
984 __m128i d2 = Shuf(kShuf, d0);
985 __m128i d3 = Shuf(kShuf, d1);
986 __m128i d4 = Xor(d0, d1);
987 __m128i d5 = Xor(d1, d2);
988 __m128i d6 = Xor(d2, d4);
989 __m128i d7 = _mm_set1_epi32(seed2 >> 32);
990 __m128i d8 = Mul(kMult, d2);
991 __m128i d9 = _mm_set1_epi32(seed3 >> 32);
992 __m128i d10 = _mm_set1_epi32(seed3);
993 __m128i d11 =
Add(d2, _mm_set1_epi32(seed2));
994 const char*
end = s + (n & ~static_cast<
size_t>(255));
997 z = inlined::Fetch128(s);
999 d1 = Shuf(kShuf, d1);
1004 z = inlined::Fetch128(s + 16);
1006 d6 = Shuf(kShuf, d6);
1007 d8 = Shuf(kShuf, d8);
1012 z = inlined::Fetch128(s + 32);
1014 d2 = Shuf(kShuf, d2);
1015 d4 = Shuf(kShuf, d4);
1019 z = inlined::Fetch128(s + 48);
1021 d7 = Shuf(kShuf, d7);
1022 d0 = Shuf(kShuf, d0);
1026 z = inlined::Fetch128(s + 64);
1028 d5 = Shuf(kShuf, d5);
1033 z = inlined::Fetch128(s + 80);
1035 d8 = Shuf(kShuf, d8);
1036 d1 = Shuf(kShuf, d1);
1041 z = inlined::Fetch128(s + 96);
1042 d4 = Shuf(kShuf, d4);
1043 d6 = Shuf(kShuf, d6);
1044 d8 = Mul(kMult, d8);
1049 z = inlined::Fetch128(s + 112);
1051 d0 = Shuf(kShuf, d0);
1052 d2 = Shuf(kShuf, d2);
1057 z = inlined::Fetch128(s + 128);
1059 d5 = Shuf(kShuf, d5);
1060 d7 = Shuf(kShuf, d7);
1065 z = inlined::Fetch128(s + 144);
1067 d1 = Shuf(kShuf, d1);
1071 z = inlined::Fetch128(s + 160);
1073 d6 = Shuf(kShuf, d6);
1074 d8 = Shuf(kShuf, d8);
1079 z = inlined::Fetch128(s + 176);
1081 d2 = Shuf(kShuf, d2);
1082 d4 = Shuf(kShuf, d4);
1083 d5 = Mul(kMult, d5);
1087 z = inlined::Fetch128(s + 192);
1089 d7 = Shuf(kShuf, d7);
1090 d0 = Shuf(kShuf, d0);
1095 z = inlined::Fetch128(s + 208);
1097 d5 = Shuf(kShuf, d5);
1102 z = inlined::Fetch128(s + 224);
1104 d8 = Shuf(kShuf, d8);
1105 d1 = Shuf(kShuf, d1);
1110 z = inlined::Fetch128(s + 240);
1112 d4 = Shuf(kShuf, d4);
1113 d6 = Shuf(kShuf, d6);
1114 d7 = Mul(kMult, d7);
1121 d6 =
Add(Mul(kMult, d6), _mm_cvtsi64_si128(n));
1123 d7 =
Add(_mm_shuffle_epi32(d8, (0 << 6) + (3 << 4) + (2 << 2) + (1 << 0)), d7);
1127 d0 = Mul(kMult, Shuf(kShuf, Mul(kMult, d0)));
1128 d3 = Mul(kMult, Shuf(kShuf, Mul(kMult, d3)));
1129 d9 = Mul(kMult, Shuf(kShuf, Mul(kMult, d9)));
1130 d1 = Mul(kMult, Shuf(kShuf, Mul(kMult, d1)));
1152 return len >= 512 ? Hash64Long(s, len, inlined::k2, inlined::k1) : farmhashxo::
Hash64(s, len);
1156 return len >= 512 ? Hash64Long(s, len, inlined::k1, seed) :
1161 return len >= 512 ? Hash64Long(s, len, seed0, seed1) :
1167 namespace farmhashnt {
1168 #if !can_use_sse41 || !x86_64
1172 return s == NULL ? 0 : len;
1177 return seed +
Hash32(s, len);
1192 namespace farmhashmk {
1194 #define Fetch inlined::Fetch32
1197 #define Rotate inlined::Rotate32
1200 #define Bswap inlined::Bswap32
1203 #define fmix farmhash::inlined::fmix
1207 uint32_t
a =
Fetch(s - 4 + (len >> 1));
1208 uint32_t
b =
Fetch(s + 4);
1209 uint32_t
c =
Fetch(s + len - 8);
1210 uint32_t d =
Fetch(s + (len >> 1));
1211 uint32_t e =
Fetch(s);
1212 uint32_t
f =
Fetch(s + len - 4);
1213 uint32_t
h = d * inlined::c1 + len + seed;
1218 a =
Rotate(a + f, 12) + d;
1226 for (
size_t i = 0; i < len; i++) {
1227 signed char v = s[i];
1228 b = b * inlined::c1 +
v;
1235 uint32_t
a = len,
b = len * 5,
c = 9, d = b + seed;
1237 b +=
Fetch(s + len - 4);
1238 c +=
Fetch(s + ((len >> 1) & 4));
1250 uint32_t
h = len,
g = inlined::c1 * len,
f =
g;
1251 uint32_t a0 =
Rotate(
Fetch(s + len - 4) * inlined::c1, 17) * inlined::c2;
1252 uint32_t a1 =
Rotate(
Fetch(s + len - 8) * inlined::c1, 17) * inlined::c2;
1253 uint32_t a2 =
Rotate(
Fetch(s + len - 16) * inlined::c1, 17) * inlined::c2;
1254 uint32_t a3 =
Rotate(
Fetch(s + len - 12) * inlined::c1, 17) * inlined::c2;
1255 uint32_t a4 =
Rotate(
Fetch(s + len - 20) * inlined::c1, 17) * inlined::c2;
1258 h = h * 5 + 0xe6546b64;
1261 h = h * 5 + 0xe6546b64;
1264 g = g * 5 + 0xe6546b64;
1267 g = g * 5 + 0xe6546b64;
1270 size_t iters = (len - 1) / 20;
1273 uint32_t
b =
Fetch(s + 4);
1274 uint32_t
c =
Fetch(s + 8);
1275 uint32_t d =
Fetch(s + 12);
1276 uint32_t e =
Fetch(s + 16);
1286 }
while (--iters != 0);
1287 g =
Rotate(g, 11) * inlined::c1;
1288 g =
Rotate(g, 17) * inlined::c1;
1289 f =
Rotate(f, 11) * inlined::c1;
1290 f =
Rotate(f, 17) * inlined::c1;
1292 h = h * 5 + 0xe6546b64;
1293 h =
Rotate(h, 17) * inlined::c1;
1295 h = h * 5 + 0xe6546b64;
1296 h =
Rotate(h, 17) * inlined::c1;
1310 namespace farmhashsu {
1311 #if !can_use_sse42 || !can_use_aesni
1315 return s == NULL ? 0 : len;
1320 return seed +
Hash32(s, len);
1326 #define Fetch inlined::Fetch32
1329 #define Rotate inlined::Rotate32
1332 #define Bswap inlined::Bswap32
1336 STATIC_INLINE __m128i Xor(__m128i
x, __m128i
y) {
return _mm_xor_si128(x, y); }
1337 STATIC_INLINE __m128i Or(__m128i
x, __m128i
y) {
return _mm_or_si128(x, y); }
1338 STATIC_INLINE __m128i Mul(__m128i
x, __m128i
y) {
return _mm_mullo_epi32(x, y); }
1341 return Or(_mm_slli_epi32(x, c),
1342 _mm_srli_epi32(x, 32 - c));
1344 STATIC_INLINE __m128i Rol17(__m128i x) {
return RotateLeft(x, 17); }
1345 STATIC_INLINE __m128i Rol19(__m128i x) {
return RotateLeft(x, 19); }
1347 return _mm_shuffle_epi32(x, (0 << 6) + (3 << 4) + (2 << 2) + (1 << 0));
1351 const uint32_t seed = 81;
1361 uint32_t
a = len,
b = seed * inlined::c2, c = a +
b;
1362 a +=
Fetch(s + len - 4);
1363 b +=
Fetch(s + len - 20);
1364 c +=
Fetch(s + len - 16);
1368 a +=
Fetch(s + len - 12);
1369 b +=
Fetch(s + len - 8);
1373 a = _mm_crc32_u32(a, b + c);
1378 #define Mulc1(x) Mul((x), cc1)
1381 #define Mulc2(x) Mul((x), cc2)
1384 #define Murk(a, h) \
1394 const __m128i cc1 = _mm_set1_epi32(inlined::c1);
1395 const __m128i cc2 = _mm_set1_epi32(inlined::c2);
1396 __m128i
h = _mm_set1_epi32(seed);
1397 __m128i
g = _mm_set1_epi32(inlined::c1 * seed);
1399 __m128i k = _mm_set1_epi32(0xe6546b64);
1402 __m128i a = inlined::Fetch128(s);
1403 __m128i b = inlined::Fetch128(s + 16);
1404 __m128i c = inlined::Fetch128(s + (len - 15) / 2);
1405 __m128i d = inlined::Fetch128(s + len - 32);
1406 __m128i e = inlined::Fetch128(s + len - 16);
1412 __m128i be =
Add(b, Mulc1(e));
1415 h =
Add(Murk(d, h), e);
1416 k = Xor(k, _mm_shuffle_epi8(g, f));
1417 g =
Add(Xor(c, g), a);
1418 f =
Add(Xor(be, f), d);
1420 k =
Add(k, _mm_shuffle_epi8(f, h));
1423 g =
Add(_mm_set1_epi32(len), Mulc1(g));
1427 size_t iters = (len - 1) / 80;
1431 #define Chunk() do { \
1432 __m128i a = inlined::Fetch128(s); \
1433 __m128i b = inlined::Fetch128(s + 16); \
1434 __m128i c = inlined::Fetch128(s + 32); \
1435 __m128i d = inlined::Fetch128(s + 48); \
1436 __m128i e = inlined::Fetch128(s + 64); \
1439 g = Shuffle0321(g); \
1441 __m128i be = Add(b, Mulc1(e)); \
1448 k = Xor(k, _mm_shuffle_epi8(g, f)); \
1449 g = Add(Xor(c, g), a); \
1450 f = Add(Xor(be, f), d); \
1452 q = _mm_aesimc_si128(q); \
1454 k = Add(k, _mm_shuffle_epi8(f, h)); \
1461 while (iters-- != 0) {
1467 h =
Add(h, _mm_set1_epi32(len));
1481 k =
Add(k, _mm_shuffle_epi8(g, f));
1486 k = Xor(k, _mm_shuffle_epi8(f, h));
1492 s =
reinterpret_cast<char*
>(
buf);
1493 uint32_t x =
Fetch(s);
1496 x = _mm_crc32_u32(x,
Fetch(s+12));
1497 y = _mm_crc32_u32(y,
Fetch(s+16));
1498 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+20));
1499 x = _mm_crc32_u32(x,
Fetch(s+24));
1500 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+28));
1502 z = _mm_crc32_u32(z,
Fetch(s+32));
1503 x = _mm_crc32_u32(x * inlined::c1,
Fetch(s+36));
1504 y = _mm_crc32_u32(y,
Fetch(s+40));
1505 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+44));
1506 x = _mm_crc32_u32(x,
Fetch(s+48));
1507 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+52));
1508 z = _mm_crc32_u32(z,
Fetch(s+56));
1509 x = _mm_crc32_u32(x,
Fetch(s+60));
1510 return (o - x + y - z) * inlined::c1;
1525 return _mm_crc32_u32(
Hash32(s + 24, len - 24) + seed, h);
1530 namespace farmhashsa {
1535 return s == NULL ? 0 : len;
1540 return seed +
Hash32(s, len);
1546 #define Fetch inlined::Fetch32
1549 #define Rotate inlined::Rotate32
1552 #define Bswap inlined::Bswap32
1555 STATIC_INLINE __m128i
Add(__m128i x, __m128i y) {
return _mm_add_epi32(x, y); }
1556 STATIC_INLINE __m128i Xor(__m128i x, __m128i y) {
return _mm_xor_si128(x, y); }
1557 STATIC_INLINE __m128i Or(__m128i x, __m128i y) {
return _mm_or_si128(x, y); }
1558 STATIC_INLINE __m128i Mul(__m128i x, __m128i y) {
return _mm_mullo_epi32(x, y); }
1559 STATIC_INLINE __m128i Mul5(__m128i x) {
return Add(x, _mm_slli_epi32(x, 2)); }
1561 return Or(_mm_slli_epi32(x, c),
1562 _mm_srli_epi32(x, 32 - c));
1564 STATIC_INLINE __m128i Rot17(__m128i x) {
return Rotatesse(x, 17); }
1565 STATIC_INLINE __m128i Rot19(__m128i x) {
return Rotatesse(x, 19); }
1567 return _mm_shuffle_epi32(x, (0 << 6) + (3 << 4) + (2 << 2) + (1 << 0));
1571 const uint32_t seed = 81;
1581 uint32_t a = len, b = seed * inlined::c2, c = a +
b;
1582 a +=
Fetch(s + len - 4);
1583 b +=
Fetch(s + len - 20);
1584 c +=
Fetch(s + len - 16);
1588 a +=
Fetch(s + len - 12);
1589 b +=
Fetch(s + len - 8);
1593 a = _mm_crc32_u32(a, b + c);
1598 #define Mulc1(x) Mul((x), cc1)
1601 #define Mulc2(x) Mul((x), cc2)
1604 #define Murk(a, h) \
1614 const __m128i cc1 = _mm_set1_epi32(inlined::c1);
1615 const __m128i cc2 = _mm_set1_epi32(inlined::c2);
1616 __m128i h = _mm_set1_epi32(seed);
1617 __m128i g = _mm_set1_epi32(inlined::c1 * seed);
1619 __m128i k = _mm_set1_epi32(0xe6546b64);
1621 __m128i a = inlined::Fetch128(s);
1622 __m128i b = inlined::Fetch128(s + 16);
1623 __m128i c = inlined::Fetch128(s + (len - 15) / 2);
1624 __m128i d = inlined::Fetch128(s + len - 32);
1625 __m128i e = inlined::Fetch128(s + len - 16);
1630 __m128i be =
Add(b, Mulc1(e));
1633 h =
Add(Murk(d, h), e);
1634 k = Xor(k, _mm_shuffle_epi8(g, f));
1635 g =
Add(Xor(c, g), a);
1636 f =
Add(Xor(be, f), d);
1638 k =
Add(k, _mm_shuffle_epi8(f, h));
1641 g =
Add(_mm_set1_epi32(len), Mulc1(g));
1645 size_t iters = (len - 1) / 80;
1649 #define Chunk() do { \
1650 __m128i a = inlined::Fetch128(s); \
1651 __m128i b = inlined::Fetch128(s + 16); \
1652 __m128i c = inlined::Fetch128(s + 32); \
1653 __m128i d = inlined::Fetch128(s + 48); \
1654 __m128i e = inlined::Fetch128(s + 64); \
1657 g = Shuffle0321(g); \
1659 __m128i be = Add(b, Mulc1(e)); \
1662 h = Add(Murk(d, h), e); \
1663 k = Xor(k, _mm_shuffle_epi8(g, f)); \
1664 g = Add(Xor(c, g), a); \
1665 f = Add(Xor(be, f), d); \
1667 k = Add(k, _mm_shuffle_epi8(f, h)); \
1673 while (iters-- != 0) {
1679 h =
Add(h, _mm_set1_epi32(len));
1691 k =
Add(k, _mm_shuffle_epi8(g, f));
1696 k = Xor(k, _mm_shuffle_epi8(f, h));
1702 s =
reinterpret_cast<char*
>(
buf);
1703 uint32_t x =
Fetch(s);
1704 uint32_t y =
Fetch(s+4);
1705 uint32_t z =
Fetch(s+8);
1706 x = _mm_crc32_u32(x,
Fetch(s+12));
1707 y = _mm_crc32_u32(y,
Fetch(s+16));
1708 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+20));
1709 x = _mm_crc32_u32(x,
Fetch(s+24));
1710 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+28));
1712 z = _mm_crc32_u32(z,
Fetch(s+32));
1713 x = _mm_crc32_u32(x * inlined::c1,
Fetch(s+36));
1714 y = _mm_crc32_u32(y,
Fetch(s+40));
1715 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+44));
1716 x = _mm_crc32_u32(x,
Fetch(s+48));
1717 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+52));
1718 z = _mm_crc32_u32(z,
Fetch(s+56));
1719 x = _mm_crc32_u32(x,
Fetch(s+60));
1720 return (o - x + y - z) * inlined::c1;
1735 return _mm_crc32_u32(
Hash32(s + 24, len - 24) + seed, h);
1740 namespace farmhashcc {
1746 #define Fetch inlined::Fetch32
1749 #define Rotate inlined::Rotate32
1752 #define Bswap inlined::Bswap32
1755 #define fmix farmhash::inlined::fmix
1758 uint32_t a =
Fetch(s - 4 + (len >> 1));
1759 uint32_t b =
Fetch(s + 4);
1760 uint32_t c =
Fetch(s + len - 8);
1761 uint32_t d =
Fetch(s + (len >> 1));
1762 uint32_t e =
Fetch(s);
1763 uint32_t f =
Fetch(s + len - 4);
1772 for (
size_t i = 0; i < len; i++) {
1773 signed char v = s[i];
1774 b = b * inlined::c1 +
v;
1781 uint32_t a = len, b = len * 5, c = 9, d =
b;
1783 b +=
Fetch(s + len - 4);
1784 c +=
Fetch(s + ((len >> 1) & 4));
1796 uint32_t h = len, g = inlined::c1 * len, f =
g;
1797 uint32_t a0 =
Rotate(
Fetch(s + len - 4) * inlined::c1, 17) * inlined::c2;
1798 uint32_t a1 =
Rotate(
Fetch(s + len - 8) * inlined::c1, 17) * inlined::c2;
1799 uint32_t a2 =
Rotate(
Fetch(s + len - 16) * inlined::c1, 17) * inlined::c2;
1800 uint32_t a3 =
Rotate(
Fetch(s + len - 12) * inlined::c1, 17) * inlined::c2;
1801 uint32_t a4 =
Rotate(
Fetch(s + len - 20) * inlined::c1, 17) * inlined::c2;
1804 h = h * 5 + 0xe6546b64;
1807 h = h * 5 + 0xe6546b64;
1810 g = g * 5 + 0xe6546b64;
1813 g = g * 5 + 0xe6546b64;
1816 f = f * 5 + 0xe6546b64;
1817 size_t iters = (len - 1) / 20;
1819 uint32_t a0 =
Rotate(
Fetch(s) * inlined::c1, 17) * inlined::c2;
1820 uint32_t a1 =
Fetch(s + 4);
1821 uint32_t a2 =
Rotate(
Fetch(s + 8) * inlined::c1, 17) * inlined::c2;
1822 uint32_t a3 =
Rotate(
Fetch(s + 12) * inlined::c1, 17) * inlined::c2;
1823 uint32_t a4 =
Fetch(s + 16);
1826 h = h * 5 + 0xe6546b64;
1829 f = f * inlined::c1;
1832 g = g * 5 + 0xe6546b64;
1835 h = h * 5 + 0xe6546b64;
1843 }
while (--iters != 0);
1844 g =
Rotate(g, 11) * inlined::c1;
1845 g =
Rotate(g, 17) * inlined::c1;
1846 f =
Rotate(f, 11) * inlined::c1;
1847 f =
Rotate(f, 17) * inlined::c1;
1849 h = h * 5 + 0xe6546b64;
1850 h =
Rotate(h, 17) * inlined::c1;
1852 h = h * 5 + 0xe6546b64;
1853 h =
Rotate(h, 17) * inlined::c1;
1868 #define Fetch farmhash::inlined::Fetch64
1871 #define Rotate inlined::Rotate64
1874 #define Bswap inlined::Bswap64
1877 #define DebugTweak farmhash::inlined::DebugTweak
1880 return val ^ (val >> 47);
1889 uint64_t a = (u ^
v) * mul;
1891 uint64_t b = (v ^
a) * mul;
1899 uint64_t
mul = inlined::k2 + len * 2;
1900 uint64_t a =
Fetch(s) + inlined::k2;
1901 uint64_t b =
Fetch(s + len - 8);
1902 uint64_t c =
Rotate(b, 37) * mul +
a;
1903 uint64_t d = (
Rotate(a, 25) +
b) * mul;
1907 uint64_t
mul = inlined::k2 + len * 2;
1913 uint8_t b = s[len >> 1];
1914 uint8_t c = s[len - 1];
1915 uint32_t y =
static_cast<uint32_t
>(
a) + (static_cast<uint32_t>(b) << 8);
1916 uint32_t z = len + (
static_cast<uint32_t
>(
c) << 2);
1917 return ShiftMix(y * inlined::k2 ^ z * inlined::k0) * inlined::k2;
1925 uint64_t
w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) {
1927 b =
Rotate(b + a + z, 21);
1932 return make_pair(a + z, b + c);
1937 const char* s, uint64_t a, uint64_t b) {
1955 signed long l = len - 16;
1957 a =
ShiftMix(a * inlined::k1) * inlined::k1;
1987 pair<uint64_t, uint64_t>
v,
w;
1990 uint64_t z = len * inlined::k1;
1991 v.first =
Rotate(y ^ inlined::k1, 49) * inlined::k1 +
Fetch(s);
1992 v.second =
Rotate(v.first, 42) * inlined::k1 +
Fetch(s + 8);
1993 w.first =
Rotate(y + z, 35) * inlined::k1 +
x;
1994 w.second =
Rotate(x +
Fetch(s + 88), 53) * inlined::k1;
1998 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) * inlined::k1;
1999 y =
Rotate(y + v.second + Fetch(s + 48), 42) * inlined::k1;
2001 y += v.first +
Fetch(s + 40);
2002 z =
Rotate(z + w.first, 33) * inlined::k1;
2007 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) * inlined::k1;
2008 y =
Rotate(y + v.second + Fetch(s + 48), 42) * inlined::k1;
2010 y += v.first +
Fetch(s + 40);
2011 z =
Rotate(z + w.first, 33) * inlined::k1;
2018 x +=
Rotate(v.first + z, 49) * inlined::k0;
2019 y = y * inlined::k0 +
Rotate(w.second, 37);
2020 z = z * inlined::k0 +
Rotate(w.first, 27);
2022 v.first *= inlined::k0;
2024 for (
size_t tail_done = 0; tail_done < len; ) {
2026 y =
Rotate(x + y, 42) * inlined::k0 + v.second;
2027 w.first +=
Fetch(s + len - tail_done + 16);
2028 x = x * inlined::k0 + w.first;
2029 z += w.second +
Fetch(s + len - tail_done);
2030 w.second += v.first;
2032 v.first *= inlined::k0;
2100 return sizeof(size_t) == 8 ?
size_t(
Hash64(s, len)) :
size_t(
Hash32(s, len));
2170 #undef Uint128High64
2172 #undef Hash64WithSeeds
2176 #undef can_use_ssse3
2177 #undef can_use_sse41
2178 #undef can_use_sse42
2179 #undef can_use_aesni
2183 #undef STATIC_INLINE
2184 #undef uint32_in_expected_order
2185 #undef uint64_in_expected_order
2195 #undef STATIC_INLINE
STATIC_INLINE uint32_t Hash32(const char *s, size_t len)
STATIC_INLINE uint128_t CityHash128WithSeed(const char *s, size_t len, uint128_t seed)
STATIC_INLINE uint32_t Hash32(const char *s, size_t len)
STATIC_INLINE pair< uint64_t, uint64_t > WeakHashLen32WithSeeds(const char *s, uint64_t a, uint64_t b)
GLenum GLuint GLenum GLsizei const GLchar * buf
STATIC_INLINE uint32_t Hash32WithSeed(const char *s, size_t len, uint32_t seed)
STATIC_INLINE uint32_t Hash32WithSeed(const char *s, size_t len, uint32_t seed)
STATIC_INLINE uint32_t Hash32(const char *s, size_t len)
STATIC_INLINE uint32_t fmix(uint32_t h)
uint128_t STATIC_INLINE Fingerprint128(const char *s, size_t len)
STATIC_INLINE uint64_t Hash64(const char *s, size_t len)
OIIO_HOSTDEVICE constexpr uint64_t Uint128Low64(const uint128_t x)
uint128_t OIIO_API Hash128WithSeed(const char *s, size_t len, uint128_t seed)
STATIC_INLINE uint64_t HashLen33to64(const char *s, size_t len)
STATIC_INLINE uint64_t Hash64WithSeed(const char *s, size_t len, uint64_t seed)
GLdouble GLdouble GLdouble z
STATIC_INLINE uint32_t Bswap32(uint32_t val)
GLboolean GLboolean GLboolean GLboolean a
STATIC_INLINE uint32_t Hash32Len13to24(const char *s, size_t len)
STATIC_INLINE uint64_t HashLen16(uint64_t u, uint64_t v)
**But if you need a result
GLdouble GLdouble GLdouble q
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 uint64_t Hash128to64(uint128_t x)
STATIC_INLINE uint32_t Hash32WithSeed(const char *s, size_t len, uint32_t seed)
STATIC_INLINE uint64_t HashLen65to96(const char *s, size_t len)
uint64_t OIIO_API Hash64WithSeeds(const char *s, size_t len, uint64_t seed0, uint64_t seed1)
size_t OIIO_API Hash(const char *s, size_t len)
STATIC_INLINE uint32_t Rotate32(uint32_t val, int shift)
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 uint128_t Uint128(uint64_t lo, uint64_t hi)
STATIC_INLINE uint64_t H32(const char *s, size_t len, uint64_t mul, uint64_t seed0=0, uint64_t seed1=0)
STATIC_INLINE uint32_t Fetch32(const char *p)
STATIC_INLINE T DebugTweak(T x)
STATIC_INLINE uint32_t BasicRotate32(uint32_t val, int shift)
STATIC_INLINE uint32_t Hash32Len5to12(const char *s, size_t len)
STATIC_INLINE uint64_t Hash64WithSeeds(const char *s, size_t len, uint64_t seed0, uint64_t seed1)
STATIC_INLINE uint32_t Mur(uint32_t a, uint32_t h)
STATIC_INLINE uint64_t ShiftMix(uint64_t val)
#define uint64_in_expected_order(x)
STATIC_INLINE uint128_t CityHash128(const char *s, size_t len)
STATIC_INLINE uint32_t Hash32Len5to12(const char *s, size_t len, uint32_t seed=0)
OIIO_HOSTDEVICE constexpr uint64_t Uint128High64(const uint128_t x)
STATIC_INLINE uint64_t H(uint64_t x, uint64_t y, uint64_t mul, int r)
#define uint32_in_expected_order(x)
STATIC_INLINE uint64_t Hash64(const char *s, size_t len)
STATIC_INLINE uint64_t HashLen17to32(const char *s, size_t len)
STATIC_INLINE uint64_t Hash64WithSeed(const char *s, size_t len, uint64_t seed)
uint64_t OIIO_API Hash64(const char *s, size_t len)
GLboolean GLboolean GLboolean b
uint32_t OIIO_API Fingerprint32(const char *s, size_t len)
STATIC_INLINE uint32_t Hash32Len13to24(const char *s, size_t len, uint32_t seed=0)
STATIC_INLINE uint64_t Rotate64(uint64_t val, int shift)
STATIC_INLINE uint64_t Bswap64(uint64_t val)
uint128_t OIIO_API Hash128(const char *s, size_t len)
#define PERMUTE3(a, b, c)
uint64_t OIIO_API Fingerprint64(const char *s, size_t len)
STATIC_INLINE uint32_t Hash32WithSeed(const char *s, size_t len, uint32_t seed)
STATIC_INLINE uint32_t Hash32(const char *s, size_t len)
STATIC_INLINE pair< uint64_t, uint64_t > WeakHashLen32WithSeeds(uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b)
GLfloat GLfloat GLfloat GLfloat h
STATIC_INLINE uint64_t HashLen0to16(const char *s, size_t len)
STATIC_INLINE uint32_t Hash32Len0to4(const char *s, size_t len)
STATIC_INLINE void simpleSwap(T &a, T &b)
FMT_CONSTEXPR20 auto bit_cast(const From &from) -> To
STATIC_INLINE uint64_t HashLen0to16(const char *s, size_t len)
STATIC_INLINE uint128_t CityMurmur(const char *s, size_t len, uint128_t seed)
uint64_t OIIO_API Hash64WithSeed(const char *s, size_t len, uint64_t seed)
STATIC_INLINE uint64_t Hash64(const char *s, size_t len)
STATIC_INLINE uint64_t Fetch64(const char *p)
GLubyte GLubyte GLubyte GLubyte w
#define OIIO_NAMESPACE_END
STATIC_INLINE uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul)
#define FARMHASH_DIE_IF_MISCONFIGURED
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 void CopyUint128(uint128_t &dst, const uint128_t src)
STATIC_INLINE uint64_t BasicRotate64(uint64_t val, int shift)
STATIC_INLINE uint64_t Hash64WithSeeds(const char *s, size_t len, uint64_t seed0, uint64_t seed1)
uint32_t OIIO_API Hash32WithSeed(const char *s, size_t len, uint32_t seed)
STATIC_INLINE uint64_t Hash64(const char *s, size_t len)
uint32_t OIIO_API Hash32(const char *s, size_t len)
std::pair< uint64_t, uint64_t > uint128_t
#define OIIO_NAMESPACE_BEGIN
ImageBuf OIIO_API mul(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
STATIC_INLINE uint64_t ShiftMix(uint64_t val)
STATIC_INLINE uint64_t Hash64WithSeed(const char *s, size_t len, uint64_t seed)
uint128_t OIIO_API Fingerprint128(const char *s, size_t len)
STATIC_INLINE uint32_t Hash32Len0to4(const char *s, size_t len, uint32_t seed=0)