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