|| defined(PERL_HASH_FUNC_SUPERFAST) \
|| defined(PERL_HASH_FUNC_MURMUR3) \
|| defined(PERL_HASH_FUNC_ONE_AT_A_TIME) \
+ || defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) \
|| defined(PERL_HASH_FUNC_ONE_AT_A_TIME_OLD) \
)
#ifdef HAS_QUAD
#define PERL_HASH_FUNC_SIPHASH
#else
-#define PERL_HASH_FUNC_ONE_AT_A_TIME
+#define PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
#endif
#endif
# define PERL_HASH_FUNC "SDBM"
# define PERL_HASH_SEED_BYTES 4
# define PERL_HASH(hash,str,len) (hash)= S_perl_hash_sdbm(PERL_HASH_SEED,(U8*)(str),(len))
+#elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD)
+# define PERL_HASH_FUNC "ONE_AT_A_TIME_HARD"
+# define PERL_HASH_SEED_BYTES 8
+# define PERL_HASH(hash,str,len) (hash)= S_perl_hash_one_at_a_time_hard(PERL_HASH_SEED,(U8*)(str),(len))
#elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME)
# define PERL_HASH_FUNC "ONE_AT_A_TIME"
# define PERL_HASH_SEED_BYTES 4
}
-/* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins
+/* This is the "One-at-a-Time" algorithm by Bob Jenkins
* from requirements by Colin Plumb.
- * (http://burtleburtle.net/bob/hash/doobs.html) */
+ * (http://burtleburtle.net/bob/hash/doobs.html)
+ * With seed/len tweak.
+ * */
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;
return (hash + (hash << 15));
}
+/* Derived from "One-at-a-Time" algorithm by Bob Jenkins */
+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;
+ U32 hash = *((U32*)seed) + len;
+
+ while (str < end) {
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ hash += *str++;
+ }
+
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ hash += seed[4];
+
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ hash += seed[5];
+
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ hash += seed[6];
+
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ hash += seed[7];
+
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ return (hash + (hash << 15));
+}
+
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;