xrpld
Loading...
Searching...
No Matches
xxhasher.h
1#pragma once
2
3#include <boost/endian/conversion.hpp>
4
5#include <xxhash.h>
6
7#include <array>
8#include <cstddef>
9#include <cstdint>
10#include <cstring>
11#include <new>
12#include <optional>
13#include <span>
14#include <type_traits>
15
16namespace beast {
17
19{
20public:
22
23private:
24 static_assert(sizeof(std::size_t) == 8, "requires 64-bit std::size_t");
25 // Have an internal buffer to avoid the streaming API
26 // A 64-byte buffer should to be big enough for us
27 static constexpr std::size_t kInternalBufferSize = 64;
28
32
34 XXH3_state_t* state_ = nullptr;
35
36 void
42
43 void
44 updateHash(void const* data, std::size_t len)
45 {
46 if (writeBuffer_.size() < len)
47 {
48 flushToState(data, len);
49 }
50 else
51 {
52 std::memcpy(writeBuffer_.data(), data, len);
53 writeBuffer_ = writeBuffer_.subspan(len);
55 }
56 }
57
58 static XXH3_state_t*
60 {
61 auto ret = XXH3_createState();
62 if (ret == nullptr)
63 throw std::bad_alloc(); // LCOV_EXCL_LINE
64 return ret;
65 }
66
67 void
68 flushToState(void const* data, std::size_t len)
69 {
70 if (state_ == nullptr)
71 {
73 if (seed_.has_value())
74 {
75 XXH3_64bits_reset_withSeed(state_, *seed_);
76 }
77 else
78 {
79 XXH3_64bits_reset(state_);
80 }
81 }
82 XXH3_64bits_update(state_, readBuffer_.data(), readBuffer_.size());
84 if ((data != nullptr) && (len != 0u))
85 {
86 XXH3_64bits_update(state_, data, len);
87 }
88 }
89
92 {
93 if (state_ != nullptr)
94 {
95 flushToState(nullptr, 0);
96 return XXH3_64bits_digest(state_);
97 }
98
99 if (seed_.has_value())
100 {
101 return XXH3_64bits_withSeed(readBuffer_.data(), readBuffer_.size(), *seed_);
102 }
103
104 return XXH3_64bits(readBuffer_.data(), readBuffer_.size());
105 }
106
107public:
108 static constexpr auto kEndian = boost::endian::order::native;
109
110 Xxhasher(Xxhasher const&) = delete;
111 Xxhasher&
112 operator=(Xxhasher const&) = delete;
113
115 {
116 resetBuffers();
117 }
118
119 ~Xxhasher() noexcept
120 {
121 if (state_ != nullptr)
122 {
123 XXH3_freeState(state_);
124 }
125 }
126
127 template <class Seed, std::enable_if_t<std::is_unsigned_v<Seed>>* = nullptr>
128 explicit Xxhasher(Seed seed) : seed_(seed)
129 {
130 resetBuffers();
131 }
132
133 template <class Seed, std::enable_if_t<std::is_unsigned_v<Seed>>* = nullptr>
134 Xxhasher(Seed seed, Seed) : seed_(seed)
135 {
136 resetBuffers();
137 }
138
139 void
140 operator()(void const* key, std::size_t len) noexcept
141 {
142 updateHash(key, len);
143 }
144
145 explicit
146 operator result_type() noexcept
147 {
148 return retrieveHash();
149 }
150};
151
152} // namespace beast
T begin(T... args)
Xxhasher(Seed seed, Seed)
Definition xxhasher.h:134
static constexpr auto kEndian
Definition xxhasher.h:108
void resetBuffers()
Definition xxhasher.h:37
XXH3_state_t * state_
Definition xxhasher.h:34
std::span< std::uint8_t > writeBuffer_
Definition xxhasher.h:31
std::array< std::uint8_t, kInternalBufferSize > buffer_
Definition xxhasher.h:29
std::span< std::uint8_t > readBuffer_
Definition xxhasher.h:30
std::optional< XXH64_hash_t > seed_
Definition xxhasher.h:33
result_type retrieveHash()
Definition xxhasher.h:91
Xxhasher & operator=(Xxhasher const &)=delete
void updateHash(void const *data, std::size_t len)
Definition xxhasher.h:44
std::size_t result_type
Definition xxhasher.h:21
Xxhasher(Xxhasher const &)=delete
void flushToState(void const *data, std::size_t len)
Definition xxhasher.h:68
static XXH3_state_t * allocState()
Definition xxhasher.h:59
static constexpr std::size_t kInternalBufferSize
Definition xxhasher.h:27
~Xxhasher() noexcept
Definition xxhasher.h:119
Xxhasher(Seed seed)
Definition xxhasher.h:128
void operator()(void const *key, std::size_t len) noexcept
Definition xxhasher.h:140
T memcpy(T... args)