summaryrefslogtreecommitdiffstats
path: root/searchlib/src/tests/attribute/raw_buffer_type_mapper/raw_buffer_type_mapper_test.cpp
blob: b6360741031800f80b1004aa0b3c6c07e701fc6c (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
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/searchlib/attribute/raw_buffer_type_mapper.h>
#include <vespa/vespalib/gtest/gtest.h>

using search::attribute::RawBufferTypeMapper;

constexpr double default_grow_factor = 1.03;

class RawBufferTypeMapperTest : public testing::Test
{
protected:
    RawBufferTypeMapper _mapper;
    RawBufferTypeMapperTest();
    ~RawBufferTypeMapperTest() override;
    std::vector<size_t> get_array_sizes(uint32_t num_array_sizes);
    std::vector<size_t> get_large_array_sizes(uint32_t num_large_arrays);
    void select_type_ids(std::vector<size_t> array_sizes);
    void setup_mapper(uint32_t max_small_subspaces_type_id, double grow_factor);
    static uint32_t calc_max_small_array_type_id(double grow_factor);
};

RawBufferTypeMapperTest::RawBufferTypeMapperTest()
    : testing::Test(),
      _mapper(5, default_grow_factor)
{
}

RawBufferTypeMapperTest::~RawBufferTypeMapperTest() = default;

void
RawBufferTypeMapperTest::setup_mapper(uint32_t max_small_subspaces_type_id, double grow_factor)
{
    _mapper = RawBufferTypeMapper(max_small_subspaces_type_id, grow_factor);
}

std::vector<size_t>
RawBufferTypeMapperTest::get_array_sizes(uint32_t num_array_sizes)
{
    std::vector<size_t> array_sizes;
    for (uint32_t type_id = 1; type_id <= num_array_sizes; ++type_id) {
        array_sizes.emplace_back(_mapper.get_array_size(type_id));
    }
    return array_sizes;
}

std::vector<size_t>
RawBufferTypeMapperTest::get_large_array_sizes(uint32_t num_large_array_sizes)
{
    setup_mapper(num_large_array_sizes * 100, default_grow_factor);
    std::vector<size_t> result;
    for (uint32_t i = 0; i < num_large_array_sizes; ++i) {
        uint32_t type_id = (i + 1) * 100;
        auto array_size = _mapper.get_array_size(type_id);
        result.emplace_back(array_size);
        EXPECT_EQ(type_id, _mapper.get_type_id(array_size));
        EXPECT_EQ(type_id, _mapper.get_type_id(array_size - 1));
        if (i + 1 == num_large_array_sizes) {
            EXPECT_EQ(0u, _mapper.get_type_id(array_size + 1));
        } else {
            EXPECT_EQ(type_id + 1, _mapper.get_type_id(array_size + 1));
        }
    }
    return result;
}

void
RawBufferTypeMapperTest::select_type_ids(std::vector<size_t> array_sizes)
{
    uint32_t type_id = 0;
    for (auto array_size : array_sizes) {
        ++type_id;
        EXPECT_EQ(type_id, _mapper.get_type_id(array_size));
        EXPECT_EQ(type_id, _mapper.get_type_id(array_size - 1));
        if (array_size == array_sizes.back()) {
            // Fallback to indirect storage, using type id 0
            EXPECT_EQ(0u, _mapper.get_type_id(array_size + 1));
        } else {
            EXPECT_EQ(type_id + 1, _mapper.get_type_id(array_size + 1));
        }
    }
}

uint32_t
RawBufferTypeMapperTest::calc_max_small_array_type_id(double grow_factor)
{
    RawBufferTypeMapper mapper(1000, grow_factor);
    return mapper.get_max_small_array_type_id(1000);
}

TEST_F(RawBufferTypeMapperTest, array_sizes_are_calculated)
{
    EXPECT_EQ((std::vector<size_t>{8, 12, 16, 20, 24}), get_array_sizes(5));
}

TEST_F(RawBufferTypeMapperTest, type_ids_are_selected)
{
    select_type_ids({8, 12, 16, 20, 24});
}

TEST_F(RawBufferTypeMapperTest, large_arrays_grows_exponentially)
{
    EXPECT_EQ((std::vector<size_t>{1148, 22796, 438572, 8429384}), get_large_array_sizes(4));
}

TEST_F(RawBufferTypeMapperTest, avoid_array_size_overflow)
{
    EXPECT_EQ(29, calc_max_small_array_type_id(2.0));
    EXPECT_EQ(379, calc_max_small_array_type_id(1.05));
    EXPECT_EQ(468, calc_max_small_array_type_id(1.04));
    EXPECT_EQ(610, calc_max_small_array_type_id(1.03));
    EXPECT_EQ(892, calc_max_small_array_type_id(1.02));
}

GTEST_MAIN_RUN_ALL_TESTS()