43 constexpr sip_hash(uint64_t k0, uint64_t k1) noexcept :
44 _v0(k0 ^ 0x736f6d6570736575),
45 _v1(k1 ^ 0x646f72616e646f6d),
46 _v2(k0 ^ 0x6c7967656e657261),
47 _v3(k1 ^ 0x7465646279746573),
52 _debug_state = debug_state_type::idle;
56 [[nodiscard]] uint64_t finish()
noexcept
59 hi_assert(_debug_state < debug_state_type::finalized);
60 _debug_state = debug_state_type::finalized;
71 m |=
static_cast<uint64_t
>(b) << 56;
72 _compress(v0,
v1, v2, v3,
m);
73 _finalize(v0,
v1, v2, v3);
75 return v0 ^
v1 ^ v2 ^ v3;
78 void add(
void const *data,
size_t size)
noexcept
81 hi_assert(_debug_state <= debug_state_type::partial);
82 _debug_state = debug_state_type::partial;
85 auto *src =
static_cast<char const *
>(data);
95 if (
hilet offset = _b & 7) {
99 for (
auto i = offset; i != offset + num_bytes; ++i) {
100 m |= char_cast<uint64_t>(src[i]) << (i * CHAR_BIT);
103 if (offset + num_bytes == 8) {
104 _compress(v0,
v1, v2, v3, std::exchange(
m, 0));
113 m = load_le<uint64_t>(src);
116 _compress(v0,
v1, v2, v3, std::exchange(
m, 0));
120 for (
auto i = 0_uz; i != todo; ++i) {
121 m |= char_cast<uint64_t>(src[i]) << (i * CHAR_BIT);
129 _b = truncate<uint8_t>(_b + size);
143 auto *src =
static_cast<char const *
>(data);
147 hi_assert(_debug_state == debug_state_type::idle);
156 for (
auto block_count = size / 8; block_count > 0; --block_count, src += 8) {
157 m = load_le<uint64_t>(src);
158 _compress(v0,
v1, v2, v3,
m);
162 m = wide_cast<uint64_t>(size & 0xff) << 56;
164 for (
auto i = 0_uz; i != (size & 7); ++i) {
165 m |= char_cast<uint64_t>(src[i]) << (i * CHAR_BIT);
167 _compress(v0,
v1, v2, v3,
m);
168 _finalize(v0,
v1, v2, v3);
170 return v0 ^
v1 ^ v2 ^ v3;
177 [[nodiscard]] uint64_t
operator()(
void const *data,
size_t size)
const noexcept
179 return complete_message(data, size);
191 enum class debug_state_type : uint8_t { idle, full, partial, finalized };
192 debug_state_type _debug_state;
195 hi_force_inline
static constexpr void _round(uint64_t& v0, uint64_t&
v1, uint64_t& v2, uint64_t& v3)
noexcept
199 v1 = std::rotl(
v1, 13);
200 v3 = std::rotl(v3, 16);
203 v0 = std::rotl(v0, 32);
207 v1 = std::rotl(
v1, 17);
208 v3 = std::rotl(v3, 21);
211 v2 = std::rotl(v2, 32);
214 static constexpr void _compress(uint64_t& v0, uint64_t&
v1, uint64_t& v2, uint64_t& v3, uint64_t m)
noexcept
219 for (
auto i = 0_uz; i != C; ++i) {
220 _round(v0,
v1, v2, v3);
225 static constexpr void _finalize(uint64_t& v0, uint64_t&
v1, uint64_t& v2, uint64_t& v3)
noexcept
228 for (
auto i = 0_uz; i != D; ++i) {
229 _round(v0,
v1, v2, v3);
#define hi_assert(expression,...)
Assert if expression is true.
Definition assert.hpp:184
#define hi_axiom_not_null(expression,...)
Assert if an expression is not nullptr.
Definition assert.hpp:257