aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/tests/predicate/predicate_ref_cache_test.cpp
blob: c8327033a8cbb15c115216243252bd28beeebb41 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for predicate_ref_cache.

#include <vespa/log/log.h>
LOG_SETUP("predicate_ref_cache_test");

#include <vespa/searchlib/predicate/predicate_ref_cache.h>
#include <vespa/vespalib/testkit/testapp.h>
#include <vector>

using namespace search;
using namespace search::predicate;

namespace {

struct MyBufferStore {
    std::vector<uint32_t> store;
    const uint32_t *getBuffer(uint32_t ref) const {
        ASSERT_LESS(ref, store.size());
        return &store[ref];
    }
    uint32_t insert(uint32_t value) {
        size_t size = store.size();
        store.push_back(value);
        return size | 0x01000000;  // size = 1
    }
    uint32_t insert(std::vector<uint32_t> data) {
        size_t size = store.size();
        uint8_t data_size = data.size();
        if (data.size() >= 0xff) {
            store.push_back(data.size());
            data_size = 0xff;
        }
        store.insert(store.end(), data.begin(), data.end());
        return size | (data_size << 24);
    }
};

TEST("require that single entries are cached") {
    MyBufferStore store;
    PredicateRefCache<MyBufferStore> cache(store);

    uint32_t ref = store.insert(42);
    uint32_t new_ref = cache.insert(ref);
    EXPECT_EQUAL(ref, new_ref);

    uint32_t ref2 = store.insert(42);
    new_ref = cache.insert(ref2);
    EXPECT_EQUAL(ref, new_ref);

    uint32_t ref3 = store.insert(44);
    new_ref = cache.insert(ref3);
    EXPECT_EQUAL(ref3, new_ref);
}

TEST("require that multivalue entries are cached") {
    MyBufferStore store;
    PredicateRefCache<MyBufferStore> cache(store);

    std::vector<uint32_t> data1 = {1, 2, 3, 4, 5};
    std::vector<uint32_t> data2 = {1, 2, 3, 4, 6};
    uint32_t ref = store.insert(data1);
    uint32_t new_ref = cache.insert(ref);
    EXPECT_EQUAL(ref, new_ref);

    uint32_t ref2 = store.insert(data1);
    new_ref = cache.insert(ref2);
    EXPECT_EQUAL(ref, new_ref);

    uint32_t ref3 = store.insert(data2);
    new_ref = cache.insert(ref3);
    EXPECT_EQUAL(ref3, new_ref);
}

TEST("require that entries can be looked up") {
    MyBufferStore store;
    PredicateRefCache<MyBufferStore> cache(store);

    uint32_t data = 42;
    EXPECT_EQUAL(0u, cache.find(&data, 1));
    uint32_t ref = store.insert(42);
    cache.insert(ref);
    EXPECT_EQUAL(ref, cache.find(&data, 1));
}

TEST("require that cache handles large entries") {
    MyBufferStore store;
    PredicateRefCache<MyBufferStore> cache(store);

    std::vector<uint32_t> data1(300);
    std::vector<uint32_t> data2(300);
    data2.back() = 42;
    uint32_t ref1 = store.insert(data1);
    cache.insert(ref1);
    EXPECT_EQUAL(ref1, cache.find(&data1[0], data1.size()));
    EXPECT_EQUAL(0u, cache.find(&data2[0], data2.size()));
    uint32_t ref2 = store.insert(data2);
    uint32_t ref = cache.insert(ref2);
    EXPECT_EQUAL(ref, ref2);
    EXPECT_EQUAL(ref2, cache.find(&data2[0], data2.size()));
}

}  // namespace

TEST_MAIN() { TEST_RUN_ALL(); }