aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/memory/unittests/chunked_memory_pool_ut.cpp
blob: 736470653bd8c2677a63d3df0c693a49c2d514f9 (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
#include <util/string/cast.h>

#include <library/cpp/testing/gtest/gtest.h>

#include <library/cpp/yt/memory/chunked_memory_pool.h>

namespace NYT {
namespace {

using ::ToString;

////////////////////////////////////////////////////////////////////////////////

TEST(TChunkedMemoryPoolTest, Absorb)
{
    TChunkedMemoryPool first;
    TChunkedMemoryPool second;
    TChunkedMemoryPool third;

    std::vector<std::pair<TStringBuf, TString>> tests;
    size_t totalSize = 0;

    auto fillPool = [&] (TChunkedMemoryPool& pool, TString prefix, int count) {
        for (int i = 0; i < count; i++) {
            TString expected = prefix + ToString(count);
            char* buf = pool.AllocateUnaligned(expected.size());
            ::memcpy(buf, expected.c_str(), expected.size());
            TStringBuf ref(buf, buf + expected.size());
            totalSize += expected.size();
            tests.emplace_back(std::move(ref), std::move(expected));
        }
    };

    auto checkAll = [&] {
        ASSERT_GE(first.GetCapacity(), first.GetSize());
        ASSERT_GE(second.GetCapacity(), second.GetSize());
        ASSERT_GE(third.GetCapacity(), third.GetSize());
        ASSERT_EQ(totalSize, first.GetSize() + second.GetSize() + third.GetSize());

        for (const auto& [ref, expected] : tests) {
            ASSERT_EQ(ref, expected);
        }
    };

    auto warmup = [&] (TChunkedMemoryPool& pool, int blockSize, int count) {
        ASSERT_EQ(pool.GetSize(), 0U);
        for (int i = 0; i < count; i++) {
            pool.AllocateUnaligned(blockSize);
        }
        pool.Clear();
        ASSERT_EQ(pool.GetSize(), 0U);
    };

    warmup(first, 20, 20'000);
    warmup(second, 20, 20'000);
    fillPool(first, "firstPool", 10'000);
    fillPool(second, "secondPool", 10'000);
    fillPool(third, "thirdPool", 10'000);
    checkAll();
    second.Absorb(std::move(third));
    checkAll();
    first.Absorb(std::move(second));
    checkAll();
    fillPool(first, "poolFirst_2", 10'000);
    fillPool(second, "poolSecond_2", 10'000);
    fillPool(third, "poolThird_2", 10'000);
    checkAll();
    third.Absorb(std::move(second));
    checkAll();
    fillPool(second, "someStr2", 10'000);
    fillPool(third, "someStr3", 10'000);
    checkAll();
}

////////////////////////////////////////////////////////////////////////////////

} // namespace
} // namespace NYT