# if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)
# define PERL_HASH_SEED PL_hash_seed
# elif PERL_HASH_SEED_BYTES == 4
-# define PERL_HASH_SEED "PeRl"
+# define PERL_HASH_SEED ((const U8 *)"PeRl")
+# elif PERL_HASH_SEED_BYTES == 8
+# define PERL_HASH_SEED ((const U8 *)"PeRlHaSh")
# elif PERL_HASH_SEED_BYTES == 16
-# define PERL_HASH_SEED "PeRlHaShhAcKpErl"
+# define PERL_HASH_SEED ((const U8 *)"PeRlHaShhAcKpErl")
# else
# error "No PERL_HASH_SEED definition for " PERL_HASH_FUNC
# endif
* are only needed to help derive these 3.
*
* U8TO32_LE(x) Read a little endian unsigned 32-bit int
- * UNALIGNED_SAFE Defined if READ_UINT32 works on non-word boundaries
+ * UNALIGNED_SAFE Defined if unaligned access is safe
* ROTL32(x,r) Rotate x left by r bits
*/
+((const U8 *)(d))[0])
#endif
-
-/* Now find best way we can to READ_UINT32 */
#if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678) && U32SIZE == 4
/* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
#define U8TO32_LE(ptr) (*((U32*)(ptr)))
#ifndef U64TYPE
/* This probably isn't going to work, but failing with a compiler error due to
lack of uint64_t is no worse than failing right now with an #error. */
-#define U64TYPE uint64_t
+#define U64 uint64_t
#endif
#endif
/* gcc recognises this code and generates a rotate instruction for CPUs with one */
#define ROTL32(x,r) (((U32)x << r) | ((U32)x >> (32 - r)))
#ifdef HAS_QUAD
- #define ROTL64(x,r) (((U64TYPE)x << r) | ((U64TYPE)x >> (64 - r)))
+ #define ROTL64(x,r) (((U64)x << r) | ((U64)x >> (64 - r)))
#endif
#endif
* It is 64 bit only.
*/
-#if defined(PERL_HASH_FUNC_SIPHASH)
#ifdef HAS_QUAD
#define U8TO64_LE(p) \
- (((U64TYPE)((p)[0]) ) | \
- ((U64TYPE)((p)[1]) << 8) | \
- ((U64TYPE)((p)[2]) << 16) | \
- ((U64TYPE)((p)[3]) << 24) | \
- ((U64TYPE)((p)[4]) << 32) | \
- ((U64TYPE)((p)[5]) << 40) | \
- ((U64TYPE)((p)[6]) << 48) | \
- ((U64TYPE)((p)[7]) << 56))
+ (((U64)((p)[0]) ) | \
+ ((U64)((p)[1]) << 8) | \
+ ((U64)((p)[2]) << 16) | \
+ ((U64)((p)[3]) << 24) | \
+ ((U64)((p)[4]) << 32) | \
+ ((U64)((p)[5]) << 40) | \
+ ((U64)((p)[6]) << 48) | \
+ ((U64)((p)[7]) << 56))
#define SIPROUND \
do { \
PERL_STATIC_INLINE U32
S_perl_hash_siphash_2_4(const unsigned char * const seed, const unsigned char *in, const STRLEN inlen) {
/* "somepseudorandomlygeneratedbytes" */
- U64TYPE v0 = UINT64_C(0x736f6d6570736575);
- U64TYPE v1 = UINT64_C(0x646f72616e646f6d);
- U64TYPE v2 = UINT64_C(0x6c7967656e657261);
- U64TYPE v3 = UINT64_C(0x7465646279746573);
-
- U64TYPE b;
- U64TYPE k0 = ((U64TYPE*)seed)[0];
- U64TYPE k1 = ((U64TYPE*)seed)[1];
- U64TYPE m;
+ U64 v0 = UINT64_C(0x736f6d6570736575);
+ U64 v1 = UINT64_C(0x646f72616e646f6d);
+ U64 v2 = UINT64_C(0x6c7967656e657261);
+ U64 v3 = UINT64_C(0x7465646279746573);
+
+ U64 b;
+ U64 k0 = ((U64*)seed)[0];
+ U64 k1 = ((U64*)seed)[1];
+ U64 m;
const int left = inlen & 7;
const U8 *end = in + inlen - left;
- b = ( ( U64TYPE )(inlen) ) << 56;
+ b = ( ( U64 )(inlen) ) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
switch( left )
{
- case 7: b |= ( ( U64TYPE )in[ 6] ) << 48;
- case 6: b |= ( ( U64TYPE )in[ 5] ) << 40;
- case 5: b |= ( ( U64TYPE )in[ 4] ) << 32;
- case 4: b |= ( ( U64TYPE )in[ 3] ) << 24;
- case 3: b |= ( ( U64TYPE )in[ 2] ) << 16;
- case 2: b |= ( ( U64TYPE )in[ 1] ) << 8;
- case 1: b |= ( ( U64TYPE )in[ 0] ); break;
+ case 7: b |= ( ( U64 )in[ 6] ) << 48;
+ case 6: b |= ( ( U64 )in[ 5] ) << 40;
+ case 5: b |= ( ( U64 )in[ 4] ) << 32;
+ case 4: b |= ( ( U64 )in[ 3] ) << 24;
+ case 3: b |= ( ( U64 )in[ 2] ) << 16;
+ case 2: b |= ( ( U64 )in[ 1] ) << 8;
+ case 1: b |= ( ( U64 )in[ 0] ); break;
case 0: break;
}
return (U32)(b & U32_MAX);
}
#endif /* defined(HAS_QUAD) */
-#endif /* defined(PERL_HASH_FUNC_SIPHASH) */
/* FYI: This is the "Super-Fast" algorithm mentioned by Bob Jenkins in
* (http://burtleburtle.net/bob/hash/doobs.html)
* http://www.azillionmonkeys.com/qed/weblicense.html
*/
-#if defined(PERL_HASH_FUNC_SUPERFAST)
+
PERL_STATIC_INLINE U32
S_perl_hash_superfast(const unsigned char * const seed, const unsigned char *str, STRLEN len) {
U32 hash = *((U32*)seed) + (U32)len;
hash ^= hash << 25;
return (hash + (hash >> 6));
}
-#endif /* defined(PERL_HASH_FUNC_SUPERFAST) */
+
/*-----------------------------------------------------------------------------
* MurmurHash3 was written by Austin Appleby, and is placed in the public
* on big endian machines, or a byte-by-byte read if the endianess is unknown.
*/
-#if defined(PERL_HASH_FUNC_MURMUR3)
+
/*-----------------------------------------------------------------------------
* Core murmurhash algorithm macros */
h1 ^= h1 >> 16;
return h1;
}
-#endif /* defined(PERL_HASH_FUNC_MURMUR3) */
-#if defined(PERL_HASH_FUNC_DJB2)
+
PERL_STATIC_INLINE U32
S_perl_hash_djb2(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
}
return hash;
}
-#endif /* defined(PERL_HASH_FUNC_DJB2) */
-#if defined(PERL_HASH_FUNC_SDBM)
PERL_STATIC_INLINE U32
S_perl_hash_sdbm(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
}
return hash;
}
-#endif /* defined(PERL_HASH_FUNC_SDBM) */
/* - ONE_AT_A_TIME_HARD is the 5.17+ recommend ONE_AT_A_TIME algorithm
* - ONE_AT_A_TIME_OLD is the unmodified 5.16 and older algorithm
* (http://burtleburtle.net/bob/hash/doobs.html)
* With seed/len tweak.
* */
-#if defined(PERL_HASH_FUNC_ONE_AT_A_TIME)
PERL_STATIC_INLINE U32
S_perl_hash_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
hash ^= (hash >> 11);
return (hash + (hash << 15));
}
-#endif /* defined(PERL_HASH_FUNC_ONE_AT_A_TIME) */
/* Derived from "One-at-a-Time" algorithm by Bob Jenkins */
-#if defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD)
PERL_STATIC_INLINE U32
S_perl_hash_one_at_a_time_hard(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
hash ^= (hash >> 11);
return (hash + (hash << 15));
}
-#endif /* defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) */
-#if defined(PERL_HASH_FUNC_ONE_AT_A_TIME_OLD)
PERL_STATIC_INLINE U32
S_perl_hash_old_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
hash ^= (hash >> 11);
return (hash + (hash << 15));
}
-#endif /* defined(PERL_HASH_FUNC_ONE_AT_A_TIME_OLD) */
#ifdef PERL_HASH_FUNC_MURMUR_HASH_64A
/* This code is from Austin Appleby and is in the public domain.
return a 32 bit hash.
Note uses unaligned 64 bit loads - will NOT work on machines with
- strict alginment requirements.
+ strict alignment requirements.
Also this code may not be suitable for big-endian machines.
*/
PERL_STATIC_INLINE U32
S_perl_hash_murmur_hash_64a (const unsigned char * const seed, const unsigned char *str, const STRLEN len)
{
- const U64TYPE m = 0xc6a4a7935bd1e995;
+ const U64 m = UINT64_C(0xc6a4a7935bd1e995);
const int r = 47;
- U64TYPE h = *((U64TYPE*)seed) ^ len;
- const U64TYPE * data = (const U64TYPE *)str;
- const U64TYPE * end = data + (len/8);
+ U64 h = *((U64*)seed) ^ len;
+ const U64 * data = (const U64 *)str;
+ const U64 * end = data + (len/8);
const unsigned char * data2;
while(data != end)
{
- U64TYPE k = *data++;
+ U64 k = *data++;
k *= m;
k ^= k >> r;
switch(len & 7)
{
- case 7: h ^= (U64TYPE)(data2[6]) << 48; /* fallthrough */
- case 6: h ^= (U64TYPE)(data2[5]) << 40; /* fallthrough */
- case 5: h ^= (U64TYPE)(data2[4]) << 32; /* fallthrough */
- case 4: h ^= (U64TYPE)(data2[3]) << 24; /* fallthrough */
- case 3: h ^= (U64TYPE)(data2[2]) << 16; /* fallthrough */
- case 2: h ^= (U64TYPE)(data2[1]) << 8; /* fallthrough */
- case 1: h ^= (U64TYPE)(data2[0]); /* fallthrough */
+ case 7: h ^= (U64)(data2[6]) << 48; /* fallthrough */
+ case 6: h ^= (U64)(data2[5]) << 40; /* fallthrough */
+ case 5: h ^= (U64)(data2[4]) << 32; /* fallthrough */
+ case 4: h ^= (U64)(data2[3]) << 24; /* fallthrough */
+ case 3: h ^= (U64)(data2[2]) << 16; /* fallthrough */
+ case 2: h ^= (U64)(data2[1]) << 8; /* fallthrough */
+ case 1: h ^= (U64)(data2[0]); /* fallthrough */
h *= m;
};
a 32 bit value
Note uses unaligned 32 bit loads - will NOT work on machines with
- strict alginment requirements.
+ strict alignment requirements.
Also this code may not be suitable for big-endian machines.
*/
h1 ^= h2 >> 17; h1 *= m;
- U64TYPE h = h1;
+ U64 h = h1;
h = (h << 32) | h2;
*/
#endif /*compile once*/
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/