diff options
-rw-r--r-- | compat/int-hash.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/compat/int-hash.cpp b/compat/int-hash.cpp index 5c009b4e..79b5dfad 100644 --- a/compat/int-hash.cpp +++ b/compat/int-hash.cpp @@ -35,15 +35,34 @@ fm_UNROLL_8 } // namespace +#define fnvhash_64_ROUND() do { hash *= 0x01000193u; hash ^= (uint8_t)*str++; } while(false) + uint64_t fnvhash_64(const void* str_, size_t size) { - const auto *str = (const char*)str_, *end = str + size; + const auto *str = (const char*)str_; uint32_t hash = 0x811c9dc5u; -fm_UNROLL_4 - for (; str != end; ++str) + size_t full = size / 8; + for (size_t i = 0; i < full; i++) { - hash *= 0x01000193u; - hash ^= (uint8_t)*str; + fnvhash_64_ROUND(); + fnvhash_64_ROUND(); + fnvhash_64_ROUND(); + fnvhash_64_ROUND(); + fnvhash_64_ROUND(); + fnvhash_64_ROUND(); + fnvhash_64_ROUND(); + fnvhash_64_ROUND(); + } + switch (size & 7u) + { + case 7: fnvhash_64_ROUND(); [[fallthrough]]; + case 6: fnvhash_64_ROUND(); [[fallthrough]]; + case 5: fnvhash_64_ROUND(); [[fallthrough]]; + case 4: fnvhash_64_ROUND(); [[fallthrough]]; + case 3: fnvhash_64_ROUND(); [[fallthrough]]; + case 2: fnvhash_64_ROUND(); [[fallthrough]]; + case 1: fnvhash_64_ROUND(); [[fallthrough]]; + case 0: break; } return hash; } |