31 #define NAMESPACE_FOR_HASH_FUNCTIONS OIIO::farmhash
35 #pragma warning( disable : 4319 )
44 #ifdef FARMHASH_ASSUME_SSSE3
45 #undef FARMHASH_ASSUME_SSSE3
46 #define FARMHASH_ASSUME_SSSE3 1
49 #ifdef FARMHASH_ASSUME_SSE41
50 #undef FARMHASH_ASSUME_SSE41
51 #define FARMHASH_ASSUME_SSE41 1
54 #ifdef FARMHASH_ASSUME_SSE42
55 #undef FARMHASH_ASSUME_SSE42
56 #define FARMHASH_ASSUME_SSE42 1
59 #ifdef FARMHASH_ASSUME_AESNI
60 #undef FARMHASH_ASSUME_AESNI
61 #define FARMHASH_ASSUME_AESNI 1
64 #ifdef FARMHASH_ASSUME_AVX
65 #undef FARMHASH_ASSUME_AVX
66 #define FARMHASH_ASSUME_AVX 1
69 #if !defined(FARMHASH_CAN_USE_CXX11) && defined(LANG_CXX11)
70 #define FARMHASH_CAN_USE_CXX11 1
72 #undef FARMHASH_CAN_USE_CXX11
73 #define FARMHASH_CAN_USE_CXX11 0
81 #if OIIO_CPLUSPLUS_VERSION >= 14
82 # define HASH_CAN_USE_CONSTEXPR 1
84 #define STATIC_INLINE OIIO_HOSTDEVICE inline OIIO_CONSTEXPR14
88 #ifndef FARMHASH_DIE_IF_MISCONFIGURED
89 #ifdef HASH_CAN_USE_CONSTEXPR
90 #define FARMHASH_DIE_IF_MISCONFIGURED
92 #define FARMHASH_DIE_IF_MISCONFIGURED do { *(char*)(len % 17) = 0; } while (0)
98 #ifdef WORDS_BIGENDIAN
99 #undef FARMHASH_BIG_ENDIAN
100 #define FARMHASH_BIG_ENDIAN 1
103 #if defined(FARMHASH_LITTLE_ENDIAN) && defined(FARMHASH_BIG_ENDIAN)
107 #if !defined(FARMHASH_LITTLE_ENDIAN) && !defined(FARMHASH_BIG_ENDIAN)
108 #define FARMHASH_UNKNOWN_ENDIAN 1
111 #if !defined(bswap_32) || !defined(bswap_64)
115 #if defined(HAVE_BUILTIN_BSWAP) || defined(__clang__) || \
116 (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || \
119 #define bswap_32(x) __builtin_bswap32(x)
120 #define bswap_64(x) __builtin_bswap64(x)
125 #if defined(FARMHASH_UNKNOWN_ENDIAN) || !defined(bswap_64)
131 #define bswap_32(x) _byteswap_ulong(x)
132 #define bswap_64(x) _byteswap_uint64(x)
134 #elif defined(__APPLE__)
137 #include <libkern/OSByteOrder.h>
140 #define bswap_32(x) OSSwapInt32(x)
141 #define bswap_64(x) OSSwapInt64(x)
143 #elif defined(__sun) || defined(sun)
145 #include <sys/byteorder.h>
148 #define bswap_32(x) BSWAP_32(x)
149 #define bswap_64(x) BSWAP_64(x)
151 #elif defined(__FreeBSD__)
153 #include <sys/endian.h>
156 #define bswap_32(x) bswap32(x)
157 #define bswap_64(x) bswap64(x)
159 #elif defined(__OpenBSD__)
161 #include <sys/types.h>
164 #define bswap_32(x) swap32(x)
165 #define bswap_64(x) swap64(x)
167 #elif defined(__NetBSD__)
169 #include <sys/types.h>
170 #include <machine/bswap.h>
171 #if defined(__BSWAP_RENAME) && !defined(__bswap_32)
174 #define bswap_32(x) bswap32(x)
175 #define bswap_64(x) bswap64(x)
182 #include <byteswap.h>
186 #ifdef WORDS_BIGENDIAN
187 #define FARMHASH_BIG_ENDIAN 1
193 #ifdef FARMHASH_BIG_ENDIAN
194 #define uint32_in_expected_order(x) (bswap_32(x))
195 #define uint64_in_expected_order(x) (bswap_64(x))
197 #define uint32_in_expected_order(x) (x)
198 #define uint64_in_expected_order(x) (x)
201 #if !defined(FARMHASH_UINT128_T_DEFINED)
202 #define uint128_t OIIO::farmhash::uint128_t
206 template <
typename T>
213 #define Uint128 OIIO::farmhash::Uint128
214 #define CopyUint128 OIIO::farmhash::CopyUint128
215 #define Uint128Low64 OIIO::farmhash::Uint128Low64
216 #define Uint128High64 OIIO::farmhash::Uint128High64
217 #define Hash128to64 OIIO::farmhash::Hash128to64
226 #if !defined(HASH_CAN_USE_CONSTEXPR) || HASH_CAN_USE_CONSTEXPR == 0
230 memcpy(&result, p,
sizeof(result));
236 memcpy(&result, p,
sizeof(result));
242 template <
typename T>
245 for (
size_t i = 0; i <
sizeof(
T); i++)
246 reinterpret_cast<char *>(&result)[i] = p[i];
251 return FetchType<uint64_t>(p);
255 return FetchType<uint32_t>(p);
261 const int S =
sizeof(
T);
265 for (
int i = 0; i < S/2; i++) {
266 int hi = 8 * (7 - i);
268 int shift = 8 * (S - (2*i + 1));
269 T lo_mask = mask << lo;
270 T hi_mask = mask << hi;
271 T new_lo = (v & hi_mask) >> shift;
272 T new_hi = (v & lo_mask) << shift;
273 result |= (new_lo | new_hi);
280 #define bswap_32(x) bswap<uint32_t>(x)
281 #define bswap_64(x) bswap<uint64_t>(x)
292 return shift == 0 ? val : ((val >> shift) | (val << (32 - shift)));
297 return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
300 #if defined(_MSC_VER) && defined(FARMHASH_ROTR)
303 return sizeof(
unsigned long) ==
sizeof(val) ?
309 return sizeof(
unsigned long) ==
sizeof(val) ?
332 #define FARMHASH_DEBUG 0
334 #if !defined(FARMHASH_DEBUG) && (!defined(NDEBUG) || defined(_DEBUG))
335 #define FARMHASH_DEBUG 1
348 #if defined (__x86_64) || defined (__x86_64__)
355 #if defined(__i386__) || defined(__i386) || defined(__X86__)
361 #if !defined(is_64bit)
362 #define is_64bit (x86_64 || (sizeof(void*) == 8))
366 #if defined(__SSSE3__) || defined(FARMHASH_ASSUME_SSSE3)
368 #include <immintrin.h>
369 #define can_use_ssse3 1
373 #define can_use_ssse3 0
377 #if defined(__SSE4_1__) || defined(FARMHASH_ASSUME_SSE41)
379 #include <immintrin.h>
380 #define can_use_sse41 1
384 #define can_use_sse41 0
388 #if defined(__SSE4_2__) || defined(FARMHASH_ASSUME_SSE42)
390 #include <nmmintrin.h>
391 #define can_use_sse42 1
395 #define can_use_sse42 0
399 #if defined(__AES__) || defined(FARMHASH_ASSUME_AESNI)
401 #include <wmmintrin.h>
402 #define can_use_aesni 1
406 #define can_use_aesni 0
410 #if defined(__AVX__) || defined(FARMHASH_ASSUME_AVX)
412 #include <immintrin.h>
413 #define can_use_avx 1
416 #define can_use_avx 0
428 #ifdef HASH_CAN_USE_CONSTEXPR
429 # undef can_use_ssse3
430 # define can_use_ssse3 0
431 # undef can_use_sse41
432 # define can_use_sse41 0
433 # undef can_use_sse42
434 # define can_use_sse42 0
435 # undef can_use_aesni
436 # define can_use_aesni 0
438 # define can_use_avx 0
445 #if !FARMHASH_CAN_USE_CXX11
450 #define PERMUTE3(a, b, c) do { simpleSwap(a, b); simpleSwap(a, c); } while (0)
459 #ifndef __CUDA_ARCH__
460 #if can_use_ssse3 || can_use_sse41 || can_use_sse42 || can_use_aesni || can_use_avx
462 return _mm_loadu_si128(reinterpret_cast<const __m128i*>(s));
468 static const uint64_t k0 = 0xc3a5c85c97cb3127ULL;
469 static const uint64_t k1 = 0xb492b66fbe98f273ULL;
470 static const uint64_t k2 = 0x9ae16a3b2f90404fULL;
473 static const uint32_t c1 = 0xcc9e2d51;
474 static const uint32_t c2 = 0x1b873593;
494 return h * 5 + 0xe6546b64;
499 if (
sizeof(x) == 4) {
524 namespace farmhashna {
526 #define Fetch farmhash::inlined::Fetch64
529 #define Rotate farmhash::inlined::Rotate64
532 #define Bswap farmhash::inlined::Bswap64
535 return val ^ (val >> 47);
544 uint64_t
a = (u ^
v) * mul;
546 uint64_t
b = (v ^
a) * mul;
554 uint64_t
mul = inlined::k2 + len * 2;
555 uint64_t
a =
Fetch(s) + inlined::k2;
556 uint64_t
b =
Fetch(s + len - 8);
557 uint64_t
c =
Rotate(b, 37) * mul +
a;
558 uint64_t d = (
Rotate(a, 25) +
b) * mul;
562 uint64_t
mul = inlined::k2 + len * 2;
568 uint8_t
b = s[len >> 1];
569 uint8_t
c = s[len - 1];
570 uint32_t
y =
static_cast<uint32_t
>(
a) + (static_cast<uint32_t>(b) << 8);
571 uint32_t
z = len + (
static_cast<uint32_t
>(
c) << 2);
572 return ShiftMix(y * inlined::k2 ^ z * inlined::k0) * inlined::k2;
580 uint64_t
mul = inlined::k2 + len * 2;
581 uint64_t
a =
Fetch(s) * inlined::k1;
582 uint64_t
b =
Fetch(s + 8);
584 uint64_t d =
Fetch(s + len - 16) * inlined::k2;
586 a +
Rotate(b + inlined::k2, 18) + c, mul);
592 uint64_t
w, uint64_t
x, uint64_t
y, uint64_t
z, uint64_t
a, uint64_t
b) {
594 b =
Rotate(b + a + z, 21);
599 return make_pair(a + z, b + c);
604 const char*
s, uint64_t
a, uint64_t
b) {
615 uint64_t
mul = inlined::k2 + len * 2;
616 uint64_t
a =
Fetch(s) * inlined::k2;
617 uint64_t
b =
Fetch(s + 8);
619 uint64_t d =
Fetch(s + len - 16) * inlined::k2;
623 uint64_t
f =
Fetch(s + 24);
624 uint64_t
g = (y +
Fetch(s + len - 32)) * mul;
625 uint64_t
h = (z +
Fetch(s + len - 24)) * mul;
627 e +
Rotate(f + a, 18) + g, mul);
631 const uint64_t seed = 81;
638 }
else if (len <= 64) {
645 uint64_t
y = seed * inlined::k1 + 113;
646 uint64_t
z =
ShiftMix(y * inlined::k2 + 113) * inlined::k2;
647 pair<uint64_t, uint64_t> v = make_pair(0, 0);
648 pair<uint64_t, uint64_t>
w = make_pair(0, 0);
649 x = x * inlined::k2 +
Fetch(s);
652 const char*
end = s + ((len - 1) / 64) * 64;
653 const char* last64 = end + ((len - 1) & 63) - 63;
654 assert(s + len - 64 == last64);
656 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) * inlined::k1;
657 y =
Rotate(y + v.second + Fetch(s + 48), 42) * inlined::k1;
659 y += v.first +
Fetch(s + 40);
660 z =
Rotate(z + w.first, 33) * inlined::k1;
666 uint64_t
mul = inlined::k1 + ((z & 0xff) << 1);
669 w.first += ((len - 1) & 63);
672 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) *
mul;
673 y =
Rotate(y + v.second + Fetch(s + 48), 42) *
mul;
675 y += v.first * 9 +
Fetch(s + 40);
694 namespace farmhashuo {
696 #define Fetch inlined::Fetch64
699 #define Rotate inlined::Rotate64
702 uint64_t
a = (x ^
y) * mul;
704 uint64_t
b = (y ^
a) * mul;
709 uint64_t seed0, uint64_t seed1) {
717 uint64_t
y = seed1 * inlined::k2 + 113;
719 pair<uint64_t, uint64_t> v = make_pair(seed0, seed1);
720 pair<uint64_t, uint64_t>
w = make_pair(0, 0);
723 uint64_t
mul = inlined::k2 + (u & 0x82);
726 const char*
end = s + ((len - 1) / 64) * 64;
727 const char* last64 = end + ((len - 1) & 63) - 63;
728 assert(s + len - 64 == last64);
730 uint64_t a0 =
Fetch(s);
731 uint64_t a1 =
Fetch(s + 8);
732 uint64_t a2 =
Fetch(s + 16);
733 uint64_t a3 =
Fetch(s + 24);
734 uint64_t a4 =
Fetch(s + 32);
735 uint64_t a5 =
Fetch(s + 40);
736 uint64_t a6 =
Fetch(s + 48);
737 uint64_t a7 =
Fetch(s + 56);
750 v.first =
Rotate(v.first, 33);
751 v.second =
Rotate(v.second, 30);
774 w.second =
Rotate(w.second, 34);
781 v.second =
Rotate(v.second, 28);
782 v.first =
Rotate(v.first, 20);
783 w.first += ((len - 1) & 63);
789 y += v.first +
Fetch(s + 40);
794 H(v.second + y, w.second + z, inlined::k2, 30) ^ x,
809 namespace farmhashxo {
811 #define Fetch inlined::Fetch64
814 #define Rotate inlined::Rotate64
817 uint64_t seed0 = 0, uint64_t seed1 = 0) {
818 uint64_t
a =
Fetch(s) * inlined::k1;
819 uint64_t
b =
Fetch(s + 8);
821 uint64_t d =
Fetch(s + len - 16) * inlined::k2;
822 uint64_t u =
Rotate(a + b, 43) +
Rotate(c, 30) + d + seed0;
823 uint64_t v = a +
Rotate(b + inlined::k2, 18) + c + seed1;
831 uint64_t mul0 = inlined::k2 - 30;
832 uint64_t mul1 = inlined::k2 - 30 + 2 * len;
833 uint64_t h0 =
H32(s, 32, mul0);
834 uint64_t h1 =
H32(s + len - 32, 32, mul1);
835 return ((h1 * mul1) + h0) * mul1;
840 uint64_t mul0 = inlined::k2 - 114;
841 uint64_t mul1 = inlined::k2 - 114 + 2 * len;
842 uint64_t h0 =
H32(s, 32, mul0);
843 uint64_t h1 =
H32(s + 32, 32, mul1);
844 uint64_t h2 =
H32(s + len - 32, 32, mul1, h0, h1);
845 return (h2 * 9 + (h0 >> 17) + (h1 >> 21)) * mul1;
855 }
else if (len <= 64) {
857 }
else if (len <= 96) {
859 }
else if (len <= 256) {
874 namespace farmhashte {
875 #if !can_use_sse41 || !x86_64
879 return s == NULL ? 0 : len;
884 return seed +
Hash64(s, len);
888 uint64_t seed0, uint64_t seed1) {
890 return seed0 + seed1 +
Hash64(s, len);
896 #define Fetch inlined::Fetch64
899 #define Rotate inlined::Rotate64
902 #define Bswap inlined::Bswap64
906 STATIC_INLINE __m128i Xor(__m128i
x, __m128i
y) {
return _mm_xor_si128(x, y); }
907 STATIC_INLINE __m128i Mul(__m128i
x, __m128i
y) {
return _mm_mullo_epi32(x, y); }
908 STATIC_INLINE __m128i Shuf(__m128i
x, __m128i
y) {
return _mm_shuffle_epi8(y, x); }
913 uint64_t seed0, uint64_t seed1) {
914 const __m128i kShuf =
915 _mm_set_epi8(4, 11, 10, 5, 8, 15, 6, 9, 12, 2, 14, 13, 0, 7, 3, 1);
916 const __m128i kMult =
917 _mm_set_epi8(0xbd, 0xd6, 0x33, 0x39, 0x45, 0x54, 0xfa, 0x03,
918 0x34, 0x3e, 0x33, 0xed, 0xcc, 0x9e, 0x2d, 0x51);
919 uint64_t seed2 = (seed0 + 113) * (seed1 + 9);
920 uint64_t seed3 = (
Rotate(seed0, 23) + 27) * (
Rotate(seed1, 30) + 111);
921 __m128i d0 = _mm_cvtsi64_si128(seed0);
922 __m128i d1 = _mm_cvtsi64_si128(seed1);
923 __m128i d2 = Shuf(kShuf, d0);
924 __m128i d3 = Shuf(kShuf, d1);
925 __m128i d4 = Xor(d0, d1);
926 __m128i d5 = Xor(d1, d2);
927 __m128i d6 = Xor(d2, d4);
928 __m128i d7 = _mm_set1_epi32(seed2 >> 32);
929 __m128i d8 = Mul(kMult, d2);
930 __m128i d9 = _mm_set1_epi32(seed3 >> 32);
931 __m128i d10 = _mm_set1_epi32(seed3);
932 __m128i d11 =
Add(d2, _mm_set1_epi32(seed2));
933 const char*
end = s + (n & ~static_cast<
size_t>(255));
936 z = inlined::Fetch128(s);
938 d1 = Shuf(kShuf, d1);
943 z = inlined::Fetch128(s + 16);
945 d6 = Shuf(kShuf, d6);
946 d8 = Shuf(kShuf, d8);
951 z = inlined::Fetch128(s + 32);
953 d2 = Shuf(kShuf, d2);
954 d4 = Shuf(kShuf, d4);
958 z = inlined::Fetch128(s + 48);
960 d7 = Shuf(kShuf, d7);
961 d0 = Shuf(kShuf, d0);
965 z = inlined::Fetch128(s + 64);
967 d5 = Shuf(kShuf, d5);
972 z = inlined::Fetch128(s + 80);
974 d8 = Shuf(kShuf, d8);
975 d1 = Shuf(kShuf, d1);
980 z = inlined::Fetch128(s + 96);
981 d4 = Shuf(kShuf, d4);
982 d6 = Shuf(kShuf, d6);
988 z = inlined::Fetch128(s + 112);
990 d0 = Shuf(kShuf, d0);
991 d2 = Shuf(kShuf, d2);
996 z = inlined::Fetch128(s + 128);
998 d5 = Shuf(kShuf, d5);
999 d7 = Shuf(kShuf, d7);
1004 z = inlined::Fetch128(s + 144);
1006 d1 = Shuf(kShuf, d1);
1010 z = inlined::Fetch128(s + 160);
1012 d6 = Shuf(kShuf, d6);
1013 d8 = Shuf(kShuf, d8);
1018 z = inlined::Fetch128(s + 176);
1020 d2 = Shuf(kShuf, d2);
1021 d4 = Shuf(kShuf, d4);
1022 d5 = Mul(kMult, d5);
1026 z = inlined::Fetch128(s + 192);
1028 d7 = Shuf(kShuf, d7);
1029 d0 = Shuf(kShuf, d0);
1034 z = inlined::Fetch128(s + 208);
1036 d5 = Shuf(kShuf, d5);
1041 z = inlined::Fetch128(s + 224);
1043 d8 = Shuf(kShuf, d8);
1044 d1 = Shuf(kShuf, d1);
1049 z = inlined::Fetch128(s + 240);
1051 d4 = Shuf(kShuf, d4);
1052 d6 = Shuf(kShuf, d6);
1053 d7 = Mul(kMult, d7);
1060 d6 =
Add(Mul(kMult, d6), _mm_cvtsi64_si128(n));
1062 d7 =
Add(_mm_shuffle_epi32(d8, (0 << 6) + (3 << 4) + (2 << 2) + (1 << 0)), d7);
1066 d0 = Mul(kMult, Shuf(kShuf, Mul(kMult, d0)));
1067 d3 = Mul(kMult, Shuf(kShuf, Mul(kMult, d3)));
1068 d9 = Mul(kMult, Shuf(kShuf, Mul(kMult, d9)));
1069 d1 = Mul(kMult, Shuf(kShuf, Mul(kMult, d1)));
1091 return len >= 512 ? Hash64Long(s, len, inlined::k2, inlined::k1) : farmhashxo::
Hash64(s, len);
1095 return len >= 512 ? Hash64Long(s, len, inlined::k1, seed) :
1100 return len >= 512 ? Hash64Long(s, len, seed0, seed1) :
1106 namespace farmhashnt {
1107 #if !can_use_sse41 || !x86_64
1111 return s == NULL ? 0 : len;
1116 return seed +
Hash32(s, len);
1131 namespace farmhashmk {
1133 #define Fetch inlined::Fetch32
1136 #define Rotate inlined::Rotate32
1139 #define Bswap inlined::Bswap32
1142 #define fmix farmhash::inlined::fmix
1146 uint32_t
a =
Fetch(s - 4 + (len >> 1));
1147 uint32_t
b =
Fetch(s + 4);
1148 uint32_t
c =
Fetch(s + len - 8);
1149 uint32_t d =
Fetch(s + (len >> 1));
1150 uint32_t e =
Fetch(s);
1151 uint32_t
f =
Fetch(s + len - 4);
1152 uint32_t
h = d * inlined::c1 + len + seed;
1157 a =
Rotate(a + f, 12) + d;
1165 for (
size_t i = 0; i < len; i++) {
1166 signed char v = s[i];
1167 b = b * inlined::c1 +
v;
1174 uint32_t
a = len,
b = len * 5,
c = 9, d = b + seed;
1176 b +=
Fetch(s + len - 4);
1177 c +=
Fetch(s + ((len >> 1) & 4));
1189 uint32_t
h = len,
g = inlined::c1 * len,
f =
g;
1190 uint32_t a0 =
Rotate(
Fetch(s + len - 4) * inlined::c1, 17) * inlined::c2;
1191 uint32_t a1 =
Rotate(
Fetch(s + len - 8) * inlined::c1, 17) * inlined::c2;
1192 uint32_t a2 =
Rotate(
Fetch(s + len - 16) * inlined::c1, 17) * inlined::c2;
1193 uint32_t a3 =
Rotate(
Fetch(s + len - 12) * inlined::c1, 17) * inlined::c2;
1194 uint32_t a4 =
Rotate(
Fetch(s + len - 20) * inlined::c1, 17) * inlined::c2;
1197 h = h * 5 + 0xe6546b64;
1200 h = h * 5 + 0xe6546b64;
1203 g = g * 5 + 0xe6546b64;
1206 g = g * 5 + 0xe6546b64;
1209 size_t iters = (len - 1) / 20;
1212 uint32_t
b =
Fetch(s + 4);
1213 uint32_t
c =
Fetch(s + 8);
1214 uint32_t d =
Fetch(s + 12);
1215 uint32_t e =
Fetch(s + 16);
1225 }
while (--iters != 0);
1226 g =
Rotate(g, 11) * inlined::c1;
1227 g =
Rotate(g, 17) * inlined::c1;
1228 f =
Rotate(f, 11) * inlined::c1;
1229 f =
Rotate(f, 17) * inlined::c1;
1231 h = h * 5 + 0xe6546b64;
1232 h =
Rotate(h, 17) * inlined::c1;
1234 h = h * 5 + 0xe6546b64;
1235 h =
Rotate(h, 17) * inlined::c1;
1249 namespace farmhashsu {
1250 #if !can_use_sse42 || !can_use_aesni
1254 return s == NULL ? 0 : len;
1259 return seed +
Hash32(s, len);
1265 #define Fetch inlined::Fetch32
1268 #define Rotate inlined::Rotate32
1271 #define Bswap inlined::Bswap32
1275 STATIC_INLINE __m128i Xor(__m128i
x, __m128i
y) {
return _mm_xor_si128(x, y); }
1276 STATIC_INLINE __m128i Or(__m128i
x, __m128i
y) {
return _mm_or_si128(x, y); }
1277 STATIC_INLINE __m128i Mul(__m128i
x, __m128i
y) {
return _mm_mullo_epi32(x, y); }
1280 return Or(_mm_slli_epi32(x, c),
1281 _mm_srli_epi32(x, 32 - c));
1283 STATIC_INLINE __m128i Rol17(__m128i x) {
return RotateLeft(x, 17); }
1284 STATIC_INLINE __m128i Rol19(__m128i x) {
return RotateLeft(x, 19); }
1286 return _mm_shuffle_epi32(x, (0 << 6) + (3 << 4) + (2 << 2) + (1 << 0));
1290 const uint32_t seed = 81;
1300 uint32_t
a = len,
b = seed * inlined::c2, c = a +
b;
1301 a +=
Fetch(s + len - 4);
1302 b +=
Fetch(s + len - 20);
1303 c +=
Fetch(s + len - 16);
1307 a +=
Fetch(s + len - 12);
1308 b +=
Fetch(s + len - 8);
1312 a = _mm_crc32_u32(a, b + c);
1317 #define Mulc1(x) Mul((x), cc1)
1320 #define Mulc2(x) Mul((x), cc2)
1323 #define Murk(a, h) \
1333 const __m128i cc1 = _mm_set1_epi32(inlined::c1);
1334 const __m128i cc2 = _mm_set1_epi32(inlined::c2);
1335 __m128i
h = _mm_set1_epi32(seed);
1336 __m128i
g = _mm_set1_epi32(inlined::c1 * seed);
1338 __m128i k = _mm_set1_epi32(0xe6546b64);
1341 __m128i a = inlined::Fetch128(s);
1342 __m128i b = inlined::Fetch128(s + 16);
1343 __m128i c = inlined::Fetch128(s + (len - 15) / 2);
1344 __m128i d = inlined::Fetch128(s + len - 32);
1345 __m128i e = inlined::Fetch128(s + len - 16);
1351 __m128i be =
Add(b, Mulc1(e));
1354 h =
Add(Murk(d, h), e);
1355 k = Xor(k, _mm_shuffle_epi8(g, f));
1356 g =
Add(Xor(c, g), a);
1357 f =
Add(Xor(be, f), d);
1359 k =
Add(k, _mm_shuffle_epi8(f, h));
1362 g =
Add(_mm_set1_epi32(len), Mulc1(g));
1366 size_t iters = (len - 1) / 80;
1370 #define Chunk() do { \
1371 __m128i a = inlined::Fetch128(s); \
1372 __m128i b = inlined::Fetch128(s + 16); \
1373 __m128i c = inlined::Fetch128(s + 32); \
1374 __m128i d = inlined::Fetch128(s + 48); \
1375 __m128i e = inlined::Fetch128(s + 64); \
1378 g = Shuffle0321(g); \
1380 __m128i be = Add(b, Mulc1(e)); \
1387 k = Xor(k, _mm_shuffle_epi8(g, f)); \
1388 g = Add(Xor(c, g), a); \
1389 f = Add(Xor(be, f), d); \
1391 q = _mm_aesimc_si128(q); \
1393 k = Add(k, _mm_shuffle_epi8(f, h)); \
1400 while (iters-- != 0) {
1406 h =
Add(h, _mm_set1_epi32(len));
1420 k =
Add(k, _mm_shuffle_epi8(g, f));
1425 k = Xor(k, _mm_shuffle_epi8(f, h));
1431 s =
reinterpret_cast<char*
>(
buf);
1432 uint32_t x =
Fetch(s);
1435 x = _mm_crc32_u32(x,
Fetch(s+12));
1436 y = _mm_crc32_u32(y,
Fetch(s+16));
1437 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+20));
1438 x = _mm_crc32_u32(x,
Fetch(s+24));
1439 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+28));
1441 z = _mm_crc32_u32(z,
Fetch(s+32));
1442 x = _mm_crc32_u32(x * inlined::c1,
Fetch(s+36));
1443 y = _mm_crc32_u32(y,
Fetch(s+40));
1444 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+44));
1445 x = _mm_crc32_u32(x,
Fetch(s+48));
1446 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+52));
1447 z = _mm_crc32_u32(z,
Fetch(s+56));
1448 x = _mm_crc32_u32(x,
Fetch(s+60));
1449 return (o - x + y - z) * inlined::c1;
1464 return _mm_crc32_u32(
Hash32(s + 24, len - 24) + seed, h);
1469 namespace farmhashsa {
1474 return s == NULL ? 0 : len;
1479 return seed +
Hash32(s, len);
1485 #define Fetch inlined::Fetch32
1488 #define Rotate inlined::Rotate32
1491 #define Bswap inlined::Bswap32
1494 STATIC_INLINE __m128i
Add(__m128i x, __m128i y) {
return _mm_add_epi32(x, y); }
1495 STATIC_INLINE __m128i Xor(__m128i x, __m128i y) {
return _mm_xor_si128(x, y); }
1496 STATIC_INLINE __m128i Or(__m128i x, __m128i y) {
return _mm_or_si128(x, y); }
1497 STATIC_INLINE __m128i Mul(__m128i x, __m128i y) {
return _mm_mullo_epi32(x, y); }
1498 STATIC_INLINE __m128i Mul5(__m128i x) {
return Add(x, _mm_slli_epi32(x, 2)); }
1500 return Or(_mm_slli_epi32(x, c),
1501 _mm_srli_epi32(x, 32 - c));
1503 STATIC_INLINE __m128i Rot17(__m128i x) {
return Rotatesse(x, 17); }
1504 STATIC_INLINE __m128i Rot19(__m128i x) {
return Rotatesse(x, 19); }
1506 return _mm_shuffle_epi32(x, (0 << 6) + (3 << 4) + (2 << 2) + (1 << 0));
1510 const uint32_t seed = 81;
1520 uint32_t a = len, b = seed * inlined::c2, c = a +
b;
1521 a +=
Fetch(s + len - 4);
1522 b +=
Fetch(s + len - 20);
1523 c +=
Fetch(s + len - 16);
1527 a +=
Fetch(s + len - 12);
1528 b +=
Fetch(s + len - 8);
1532 a = _mm_crc32_u32(a, b + c);
1537 #define Mulc1(x) Mul((x), cc1)
1540 #define Mulc2(x) Mul((x), cc2)
1543 #define Murk(a, h) \
1553 const __m128i cc1 = _mm_set1_epi32(inlined::c1);
1554 const __m128i cc2 = _mm_set1_epi32(inlined::c2);
1555 __m128i h = _mm_set1_epi32(seed);
1556 __m128i g = _mm_set1_epi32(inlined::c1 * seed);
1558 __m128i k = _mm_set1_epi32(0xe6546b64);
1560 __m128i a = inlined::Fetch128(s);
1561 __m128i b = inlined::Fetch128(s + 16);
1562 __m128i c = inlined::Fetch128(s + (len - 15) / 2);
1563 __m128i d = inlined::Fetch128(s + len - 32);
1564 __m128i e = inlined::Fetch128(s + len - 16);
1569 __m128i be =
Add(b, Mulc1(e));
1572 h =
Add(Murk(d, h), e);
1573 k = Xor(k, _mm_shuffle_epi8(g, f));
1574 g =
Add(Xor(c, g), a);
1575 f =
Add(Xor(be, f), d);
1577 k =
Add(k, _mm_shuffle_epi8(f, h));
1580 g =
Add(_mm_set1_epi32(len), Mulc1(g));
1584 size_t iters = (len - 1) / 80;
1588 #define Chunk() do { \
1589 __m128i a = inlined::Fetch128(s); \
1590 __m128i b = inlined::Fetch128(s + 16); \
1591 __m128i c = inlined::Fetch128(s + 32); \
1592 __m128i d = inlined::Fetch128(s + 48); \
1593 __m128i e = inlined::Fetch128(s + 64); \
1596 g = Shuffle0321(g); \
1598 __m128i be = Add(b, Mulc1(e)); \
1601 h = Add(Murk(d, h), e); \
1602 k = Xor(k, _mm_shuffle_epi8(g, f)); \
1603 g = Add(Xor(c, g), a); \
1604 f = Add(Xor(be, f), d); \
1606 k = Add(k, _mm_shuffle_epi8(f, h)); \
1612 while (iters-- != 0) {
1618 h =
Add(h, _mm_set1_epi32(len));
1630 k =
Add(k, _mm_shuffle_epi8(g, f));
1635 k = Xor(k, _mm_shuffle_epi8(f, h));
1641 s =
reinterpret_cast<char*
>(
buf);
1642 uint32_t x =
Fetch(s);
1643 uint32_t y =
Fetch(s+4);
1644 uint32_t z =
Fetch(s+8);
1645 x = _mm_crc32_u32(x,
Fetch(s+12));
1646 y = _mm_crc32_u32(y,
Fetch(s+16));
1647 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+20));
1648 x = _mm_crc32_u32(x,
Fetch(s+24));
1649 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+28));
1651 z = _mm_crc32_u32(z,
Fetch(s+32));
1652 x = _mm_crc32_u32(x * inlined::c1,
Fetch(s+36));
1653 y = _mm_crc32_u32(y,
Fetch(s+40));
1654 z = _mm_crc32_u32(z * inlined::c1,
Fetch(s+44));
1655 x = _mm_crc32_u32(x,
Fetch(s+48));
1656 y = _mm_crc32_u32(y * inlined::c1,
Fetch(s+52));
1657 z = _mm_crc32_u32(z,
Fetch(s+56));
1658 x = _mm_crc32_u32(x,
Fetch(s+60));
1659 return (o - x + y - z) * inlined::c1;
1674 return _mm_crc32_u32(
Hash32(s + 24, len - 24) + seed, h);
1679 namespace farmhashcc {
1685 #define Fetch inlined::Fetch32
1688 #define Rotate inlined::Rotate32
1691 #define Bswap inlined::Bswap32
1694 #define fmix farmhash::inlined::fmix
1697 uint32_t a =
Fetch(s - 4 + (len >> 1));
1698 uint32_t b =
Fetch(s + 4);
1699 uint32_t c =
Fetch(s + len - 8);
1700 uint32_t d =
Fetch(s + (len >> 1));
1701 uint32_t e =
Fetch(s);
1702 uint32_t f =
Fetch(s + len - 4);
1711 for (
size_t i = 0; i < len; i++) {
1712 signed char v = s[i];
1713 b = b * inlined::c1 +
v;
1720 uint32_t a = len, b = len * 5, c = 9, d =
b;
1722 b +=
Fetch(s + len - 4);
1723 c +=
Fetch(s + ((len >> 1) & 4));
1735 uint32_t h = len, g = inlined::c1 * len, f =
g;
1736 uint32_t a0 =
Rotate(
Fetch(s + len - 4) * inlined::c1, 17) * inlined::c2;
1737 uint32_t a1 =
Rotate(
Fetch(s + len - 8) * inlined::c1, 17) * inlined::c2;
1738 uint32_t a2 =
Rotate(
Fetch(s + len - 16) * inlined::c1, 17) * inlined::c2;
1739 uint32_t a3 =
Rotate(
Fetch(s + len - 12) * inlined::c1, 17) * inlined::c2;
1740 uint32_t a4 =
Rotate(
Fetch(s + len - 20) * inlined::c1, 17) * inlined::c2;
1743 h = h * 5 + 0xe6546b64;
1746 h = h * 5 + 0xe6546b64;
1749 g = g * 5 + 0xe6546b64;
1752 g = g * 5 + 0xe6546b64;
1755 f = f * 5 + 0xe6546b64;
1756 size_t iters = (len - 1) / 20;
1758 uint32_t a0 =
Rotate(
Fetch(s) * inlined::c1, 17) * inlined::c2;
1759 uint32_t a1 =
Fetch(s + 4);
1760 uint32_t a2 =
Rotate(
Fetch(s + 8) * inlined::c1, 17) * inlined::c2;
1761 uint32_t a3 =
Rotate(
Fetch(s + 12) * inlined::c1, 17) * inlined::c2;
1762 uint32_t a4 =
Fetch(s + 16);
1765 h = h * 5 + 0xe6546b64;
1768 f = f * inlined::c1;
1771 g = g * 5 + 0xe6546b64;
1774 h = h * 5 + 0xe6546b64;
1782 }
while (--iters != 0);
1783 g =
Rotate(g, 11) * inlined::c1;
1784 g =
Rotate(g, 17) * inlined::c1;
1785 f =
Rotate(f, 11) * inlined::c1;
1786 f =
Rotate(f, 17) * inlined::c1;
1788 h = h * 5 + 0xe6546b64;
1789 h =
Rotate(h, 17) * inlined::c1;
1791 h = h * 5 + 0xe6546b64;
1792 h =
Rotate(h, 17) * inlined::c1;
1807 #define Fetch farmhash::inlined::Fetch64
1810 #define Rotate inlined::Rotate64
1813 #define Bswap inlined::Bswap64
1816 #define DebugTweak farmhash::inlined::DebugTweak
1819 return val ^ (val >> 47);
1828 uint64_t a = (u ^
v) * mul;
1830 uint64_t b = (v ^
a) * mul;
1838 uint64_t
mul = inlined::k2 + len * 2;
1839 uint64_t a =
Fetch(s) + inlined::k2;
1840 uint64_t b =
Fetch(s + len - 8);
1841 uint64_t c =
Rotate(b, 37) * mul +
a;
1842 uint64_t d = (
Rotate(a, 25) +
b) * mul;
1846 uint64_t
mul = inlined::k2 + len * 2;
1852 uint8_t b = s[len >> 1];
1853 uint8_t c = s[len - 1];
1854 uint32_t y =
static_cast<uint32_t
>(
a) + (static_cast<uint32_t>(b) << 8);
1855 uint32_t z = len + (
static_cast<uint32_t
>(
c) << 2);
1856 return ShiftMix(y * inlined::k2 ^ z * inlined::k0) * inlined::k2;
1864 uint64_t
w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) {
1866 b =
Rotate(b + a + z, 21);
1871 return make_pair(a + z, b + c);
1876 const char* s, uint64_t a, uint64_t b) {
1894 signed long l = len - 16;
1896 a =
ShiftMix(a * inlined::k1) * inlined::k1;
1926 pair<uint64_t, uint64_t>
v,
w;
1929 uint64_t z = len * inlined::k1;
1930 v.first =
Rotate(y ^ inlined::k1, 49) * inlined::k1 +
Fetch(s);
1931 v.second =
Rotate(v.first, 42) * inlined::k1 +
Fetch(s + 8);
1932 w.first =
Rotate(y + z, 35) * inlined::k1 +
x;
1933 w.second =
Rotate(x +
Fetch(s + 88), 53) * inlined::k1;
1937 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) * inlined::k1;
1938 y =
Rotate(y + v.second + Fetch(s + 48), 42) * inlined::k1;
1940 y += v.first +
Fetch(s + 40);
1941 z =
Rotate(z + w.first, 33) * inlined::k1;
1946 x =
Rotate(x + y + v.first + Fetch(s + 8), 37) * inlined::k1;
1947 y =
Rotate(y + v.second + Fetch(s + 48), 42) * inlined::k1;
1949 y += v.first +
Fetch(s + 40);
1950 z =
Rotate(z + w.first, 33) * inlined::k1;
1957 x +=
Rotate(v.first + z, 49) * inlined::k0;
1958 y = y * inlined::k0 +
Rotate(w.second, 37);
1959 z = z * inlined::k0 +
Rotate(w.first, 27);
1961 v.first *= inlined::k0;
1963 for (
size_t tail_done = 0; tail_done < len; ) {
1965 y =
Rotate(x + y, 42) * inlined::k0 + v.second;
1966 w.first +=
Fetch(s + len - tail_done + 16);
1967 x = x * inlined::k0 + w.first;
1968 z += w.second +
Fetch(s + len - tail_done);
1969 w.second += v.first;
1971 v.first *= inlined::k0;
2039 return sizeof(size_t) == 8 ?
Hash64(s, len) :
Hash32(s, len);
2109 #undef Uint128High64
2111 #undef Hash64WithSeeds
2115 #undef can_use_ssse3
2116 #undef can_use_sse41
2117 #undef can_use_sse42
2118 #undef can_use_aesni
2122 #undef STATIC_INLINE
2123 #undef uint32_in_expected_order
2124 #undef uint64_in_expected_order
2134 #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)
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)