aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/containers/unittests/sharded_set_ut.cpp
blob: a954ea5151c232a4ce599795ca1b788819013835 (plain) (blame)
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