Skip to content

Commit

Permalink
removed boost::hash, it's exactly the same as std::hash
Browse files Browse the repository at this point in the history
Added mumxmuxx1 hash
  • Loading branch information
martinus committed Jun 17, 2022
1 parent b42ead0 commit 1a6323c
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 35 deletions.
8 changes: 0 additions & 8 deletions src/hashes/boost_hash/Hash.h

This file was deleted.

1 change: 0 additions & 1 deletion src/hashes/boost_hash/dependencies.cmake

This file was deleted.

26 changes: 0 additions & 26 deletions src/hashes/lehmer_hash/Hash.h

This file was deleted.

87 changes: 87 additions & 0 deletions src/hashes/mumxmumxx1_hash/Hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <string>
#include <type_traits>
#include <utility>

static const char* HashName = "mumxmumxx1";

#include <cstdint>

namespace ankerl::mixer {

// 128bit multiplication of a*b, returning low 64bits, and sets high 64bits
// Source: https://github.com/martinus/robin-hood-hashing
//
// might be worth looking what MUM hash does:
// https://github.com/vnmakarov/mum-hash/blob/master/mum.h#L103
inline uint64_t umul128(uint64_t a, uint64_t b, uint64_t* high) noexcept {
#if defined(__SIZEOF_INT128__)
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
using uint128_t = unsigned __int128;
#pragma GCC diagnostic pop
#endif

auto result = static_cast<uint128_t>(a) * static_cast<uint128_t>(b);
*high = static_cast<uint64_t>(result >> 64U);
return static_cast<uint64_t>(result);

#elif (defined(_MSC_VER) && SIZE_MAX == UINT64_MAX)
#include <intrin.h> // for __umulh
#pragma intrinsic(__umulh)
#ifndef _M_ARM64
#pragma intrinsic(_umul128)
#endif
#ifdef _M_ARM64
*high = __umulh(a, b);
return ((uint64_t)(a)) * (b);
#else
return _umul128(a, b, high);
#endif
#else
#error No hardware umul
#endif
}

// 128bit multiply a and b, xor high and low result
inline uint64_t mumx(uint64_t a, uint64_t b) {
uint64_t h;
uint64_t l = umul128(a, b, &h);
return h ^ l;
}

// 128bit multiply a and b, add high and low result
inline uint64_t muma(uint64_t a, uint64_t b) {
uint64_t h;
uint64_t l = umul128(a, b, &h);
return h + l;
}

inline uint64_t mumxmumxx1(uint64_t v) {
static constexpr auto a = UINT64_C(0x2ca7aea0ebd71d49);
static constexpr auto b = UINT64_C(0x9e49b5a3555f2295);

return mumx(mumx(v, a), v ^ b);
}

} // namespace ankerl::mixer

// very fast high quality mixer. From https://github.com/martinus/better-faster-stronger-mixer
template <typename T>
struct Hash {
size_t operator()(T const& v) const {
return ankerl::mixer::mumxmumxx1(v);
}
};

// default hash
template <>
struct Hash<std::string> {
size_t operator()(std::string const& key) const {
return std::hash<std::string>{}(key);
}
};

0 comments on commit 1a6323c

Please sign in to comment.