Last active
August 12, 2024 18:20
-
-
Save oplanre/e384ed2a4c0fea698ed0e15d24157611 to your computer and use it in GitHub Desktop.
Revisions
-
oplanre revised this gist
Aug 12, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ static constexpr zend_ulong DJBX33A(const char *str, size_t len){ zend_ulong hash = 5381; #if defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) // Version with multiplication works better on modern CPUs -
oplanre revised this gist
Aug 12, 2024 . 1 changed file with 4 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,5 @@ static constexpr T DJBX33A(const char *str, size_t len){ zend_ulong hash = 5381; #if defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) // Version with multiplication works better on modern CPUs for (; len >= 8; len -= 8, str += 8) { @@ -43,11 +42,7 @@ static constexpr T DJBX33A(const char *str, size_t len){ // EMPTY_SWITCH_DEFAULT_CASE() } #endif if constexpr (sizeof(zend_ulong) == 8) return hash | 0x8000000000000000ULL; if constexpr (sizeof(zend_ulong) == 4) return hash | 0x80000000UL; static_assert(sizeof(zend_ulong) == 8 || sizeof(zend_ulong) == 4, "Unsupported hash size"); } -
oplanre renamed this gist
Aug 12, 2024 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
oplanre created this gist
Aug 12, 2024 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,53 @@ template <typename T = ULong> static constexpr T DJBX33A(const char *str, size_t len){ std::make_unsigned_t<T> hash = 5381; #if defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) // Version with multiplication works better on modern CPUs for (; len >= 8; len -= 8, str += 8) { uint64_t chunk; std::memcpy(&chunk, str, sizeof(chunk)); hash = hash * 33 * 33 * 33 * 33 + ((chunk >> (8 * 0)) & 0xff) * 33 * 33 * 33 + ((chunk >> (8 * 1)) & 0xff) * 33 * 33 + ((chunk >> (8 * 2)) & 0xff) * 33 + ((chunk >> (8 * 3)) & 0xff); hash = hash * 33 * 33 * 33 * 33 + ((chunk >> (8 * 4)) & 0xff) * 33 * 33 * 33 + ((chunk >> (8 * 5)) & 0xff) * 33 * 33 + ((chunk >> (8 * 6)) & 0xff) * 33 + ((chunk >> (8 * 7)) & 0xff); } // Remaining bytes for (; len >= 4; len -= 4, str += 4) { hash = hash * 33 * 33 * 33 * 33 + str[0] * 33 * 33 * 33 + str[1] * 33 * 33 + str[2] * 33 + str[3]; } for (; len >= 2; len -= 2, str += 2) { hash = hash * 33 * 33 * 33 + str[0] * 33 * 33 + str[1] * 33; } if (len == 1) { hash = hash * 33 + *str; } #else // Variant with the hash unrolled eight times 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++; hash = ((hash << 5) + hash) + *str++; } // Remaining bytes 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() } #endif if constexpr (sizeof(T) == 8) return hash | 0x8000000000000000ULL; if constexpr (sizeof(T) == 4) return hash | 0x80000000UL; static_assert(sizeof(T) == 8 || sizeof(T) == 4, "Unsupported hash size"); } template <typename T, typename CharT> static constexpr T DJBX33A(const CharT *str, size_t len) { return DJBX33A<T>(reinterpret_cast<const char *>(str), len * sizeof(CharT)); }