Last active
December 10, 2015 13:09
-
-
Save do-aki/21a1259058d4c849264f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- 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