Skip to content

Instantly share code, notes, and snippets.

@do-aki
Last active December 10, 2015 13:09
Show Gist options
  • Save do-aki/21a1259058d4c849264f to your computer and use it in GitHub Desktop.
Save do-aki/21a1259058d4c849264f to your computer and use it in GitHub Desktop.
--- zend_inline_hash_func-5.6.16» 2015-12-10 22:02:42.179337112 +0900
+++ zend_inline_hash_func-7.0.0»2015-12-10 22:03:03.595338278 +0900
@@ -14,7 +14,7 @@
* numbers are not useable at all. The remaining 128 odd numbers
* (except for the number 1) work more or less all equally well. They
* all distribute in an acceptable way and this way fill a hash table
- * with an average percent of approx. 86%._
+ * with an average percent of approx. 86%.
*
* If one compares the Chi^2 values of the variants, the number 33 not
* even has the best value. But the number 33 and a few other equally
@@ -31,32 +31,40 @@
* -- Ralf S. Engelschall <rse@engelschall.com>
*/
-static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
+static zend_always_inline zend_ulong zend_inline_hash_func(const char *str, size_t len)
{
- register ulong hash = 5381;
+ register zend_ulong hash = Z_UL(5381);
/* variant with the hash unrolled eight times */
- for (; nKeyLength >= 8; nKeyLength -= 8) {
- hash = ((hash << 5) + hash) + *arKey++;
- hash = ((hash << 5) + hash) + *arKey++;
- hash = ((hash << 5) + hash) + *arKey++;
- hash = ((hash << 5) + hash) + *arKey++;
- hash = ((hash << 5) + hash) + *arKey++;
- hash = ((hash << 5) + hash) + *arKey++;
- hash = ((hash << 5) + hash) + *arKey++;
- hash = ((hash << 5) + hash) + *arKey++;
+ for (; len >= 8; len -= 8) {
+ hash = ((hash << 5) + hash) + *str++;
+ hash = ((hash << 5) + hash) + *str++;
+ hash = ((hash << 5) + hash) + *str++;
+ hash = ((hash << 5) + hash) + *str++;
+ hash = ((hash << 5) + hash) + *str++;
+ hash = ((hash << 5) + hash) + *str++;
+ hash = ((hash << 5) + hash) + *str++;
}
- switch (nKeyLength) {
- case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
- case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
- case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
- case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
- case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
- case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
- case 1: hash = ((hash << 5) + hash) + *arKey++; break;
+ switch (len) {
+ case 7: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
+ case 6: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
+ case 5: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
+ case 4: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
+ case 3: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
+ case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
+ case 1: hash = ((hash << 5) + hash) + *str++; break;
case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
}
- return hash;
+
+ /* Hash value can't be zero, so we always set the high bit */
+#if SIZEOF_ZEND_LONG == 8
+ return hash | Z_UL(0x8000000000000000);
+#elif SIZEOF_ZEND_LONG == 4
+ return hash | Z_UL(0x80000000);
+#else
+# error "Unknown SIZEOF_ZEND_LONG"
+#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment