1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include <library/cpp/yt/containers/sharded_set.h>
#include <library/cpp/testing/gtest/gtest.h>
#include <random>
namespace NYT {
namespace {
////////////////////////////////////////////////////////////////////////////////
struct TIntToShard
{
int operator()(int value) const
{
return value % 16;
}
};
using TSet = TShardedSet<int, 16, TIntToShard>;
////////////////////////////////////////////////////////////////////////////////
TEST(TShardedSetTest, Insert)
{
TSet set;
for (int i = 0; i < 4; i++) {
set.insert(i);
}
for (int i = 0; i < 4; i++) {
set.insert(i);
}
EXPECT_EQ(4u, set.size());
for (int i = 0; i < 4; i++)
EXPECT_EQ(1u, set.count(i));
EXPECT_EQ(0u, set.count(4));
}
TEST(TShardedSetTest, Erase)
{
TSet set;
for (int i = 0; i < 8; i++) {
set.insert(i);
}
EXPECT_EQ(8u, set.size());
// Remove elements one by one and check if all other elements are still there.
for (int i = 0; i < 8; i++) {
EXPECT_EQ(1u, set.count(i));
EXPECT_TRUE(set.erase(i));
EXPECT_EQ(0u, set.count(i));
EXPECT_EQ(8u - i - 1, set.size());
for (int j = i + 1; j < 8; j++) {
EXPECT_EQ(1u, set.count(j));
}
}
EXPECT_EQ(0u, set.count(8));
}
TEST(TShardedSetTest, StressTest)
{
TSet set;
constexpr int Iterations = 1'000'000;
constexpr int Values = 128;
THashSet<int> values;
auto checkEverything = [&] {
EXPECT_EQ(values.size(), set.size());
EXPECT_EQ(values.empty(), set.empty());
EXPECT_EQ(values, THashSet<int>(set.begin(), set.end()));
std::array<THashSet<int>, 16> shards;
for (int value : values) {
shards[value % 16].insert(value);
}
for (int shardIndex = 0; shardIndex < 16; ++shardIndex) {
EXPECT_EQ(shards[shardIndex], set.Shard(shardIndex));
}
for (int value = 0; value < Values; ++value) {
EXPECT_EQ(values.contains(value), set.contains(value));
EXPECT_EQ(values.count(value), set.count(value));
}
};
std::mt19937_64 rng(42);
for (int iteration = 0; iteration < Iterations; ++iteration) {
if (rng() % 100 == 0) {
set.clear();
values.clear();
checkEverything();
}
int value = rng() % Values;
if (rng() % 2 == 0) {
set.insert(value);
values.insert(value);
} else {
set.erase(value);
values.erase(value);
}
checkEverything();
}
}
////////////////////////////////////////////////////////////////////////////////
} // namespace
} // namespace NYT
|