xrpld
Loading...
Searching...
No Matches
xxhasher.cpp
1#include <xrpl/beast/hash/xxhasher.h>
2
3#include <gtest/gtest.h>
4
5#include <cstddef>
6#include <cstdint>
7#include <string>
8#include <string_view>
9
10namespace beast {
11namespace {
12
13constexpr std::string_view kInput{"Hello, xxHash!"};
14constexpr std::uint32_t kSeed{102};
15constexpr std::uint32_t kOtherSeed{103};
16
17// The multiple-update and one-update cases hash the same kRepeatCount copies of
18// kInput, so their expected digests must agree.
19constexpr std::size_t kRepeatCount{100};
20constexpr std::size_t kBigObjectRepeat{20};
21
22// Returns text repeated the given number of times.
23//
24// Used by the cases that hash a large object in one update, so that their
25// expected digest can be compared against the cases that feed the same bytes
26// in as many small updates.
27std::string
28repeat(std::string_view text, std::size_t times)
29{
30 std::string out;
31 out.reserve(text.size() * times);
32 for (std::size_t i = 0; i < times; ++i)
33 out += text;
34 return out;
35}
36
37} // namespace
38
39TEST(XXHasher, without_seed)
40{
41 Xxhasher hasher{};
42 hasher(kInput.data(), kInput.size());
43
44 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 16042857369214894119ULL);
45}
46
47TEST(XXHasher, with_seed)
48{
49 Xxhasher hasher{kSeed};
50 hasher(kInput.data(), kInput.size());
51
52 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 14440132435660934800ULL);
53}
54
55TEST(XXHasher, with_two_seeds)
56{
57 Xxhasher hasher{kSeed, kOtherSeed};
58 hasher(kInput.data(), kInput.size());
59
60 // The second seed is ignored, so this matches the single-seed result.
61 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 14440132435660934800ULL);
62}
63
64// Feeds the bytes in as kRepeatCount small updates, never materializing the full object.
65// big_object_with_one_update_without_seed below hashes the same bytes in a single
66// update and must agree, which is what exercises xxHash's internal buffering.
67TEST(XXHasher, big_object_with_multiple_small_updates_without_seed)
68{
69 Xxhasher hasher{};
70 for (std::size_t i = 0; i < kRepeatCount; ++i)
71 hasher(kInput.data(), kInput.size());
72
73 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 15296278154063476002ULL);
74}
75
76TEST(XXHasher, big_object_with_multiple_small_updates_with_seed)
77{
78 Xxhasher hasher{kOtherSeed};
79 for (std::size_t i = 0; i < kRepeatCount; ++i)
80 hasher(kInput.data(), kInput.size());
81
82 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 17285302196561698791ULL);
83}
84
85TEST(XXHasher, big_object_with_small_and_big_updates_without_seed)
86{
87 Xxhasher hasher{};
88 std::string const bigObject = repeat(kInput, kBigObjectRepeat);
89
90 hasher(kInput.data(), kInput.size());
91 hasher(bigObject.data(), bigObject.size());
92 hasher(kInput.data(), kInput.size());
93
94 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 1865045178324729219ULL);
95}
96
97TEST(XXHasher, big_object_with_small_and_big_updates_with_seed)
98{
99 Xxhasher hasher{kOtherSeed};
100 std::string const bigObject = repeat(kInput, kBigObjectRepeat);
101
102 hasher(kInput.data(), kInput.size());
103 hasher(bigObject.data(), bigObject.size());
104 hasher(kInput.data(), kInput.size());
105
106 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 16189862915636005281ULL);
107}
108
109TEST(XXHasher, big_object_with_one_update_without_seed)
110{
111 Xxhasher hasher{};
112 std::string const object = repeat(kInput, kRepeatCount);
113 hasher(object.data(), object.size());
114
115 // Hashing the whole object at once must match hashing it in kRepeatCount pieces.
116 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 15296278154063476002ULL);
117}
118
119TEST(XXHasher, big_object_with_one_update_with_seed)
120{
121 Xxhasher hasher{kOtherSeed};
122 std::string const object = repeat(kInput, kRepeatCount);
123 hasher(object.data(), object.size());
124
125 EXPECT_EQ(static_cast<Xxhasher::result_type>(hasher), 17285302196561698791ULL);
126}
127
128TEST(XXHasher, operator_result_type_does_not_change_internal_state)
129{
130 {
131 Xxhasher hasher;
132 std::string const object{"Hello xxhash"};
133 hasher(object.data(), object.size());
134
135 EXPECT_EQ(
136 static_cast<Xxhasher::result_type>(hasher), static_cast<Xxhasher::result_type>(hasher));
137 }
138 {
139 Xxhasher hasher;
140 std::string const object = repeat(kInput, kRepeatCount);
141 hasher(object.data(), object.size());
142
143 EXPECT_EQ(hasher.operator Xxhasher::result_type(), hasher.operator Xxhasher::result_type());
144 }
145}
146
147} // namespace beast
std::size_t result_type
Definition xxhasher.h:21
T data(T... args)
TEST(BasicSecondsClock, now)
T reserve(T... args)
T size(T... args)