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