aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/tests/lru-cache.cc
blob: 091d3d5ede192eb4561d84c7d02d554868a6b7ea (plain)
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
122
123
124
125
126
127
128
129
130
#include "lru-cache.hh"
#include <gtest/gtest.h>

namespace nix {

    /* ----------------------------------------------------------------------------
     * size
     * --------------------------------------------------------------------------*/

    TEST(LRUCache, sizeOfEmptyCacheIsZero) {
        LRUCache<std::string, std::string> c(10);
        ASSERT_EQ(c.size(), 0);
    }

    TEST(LRUCache, sizeOfSingleElementCacheIsOne) {
        LRUCache<std::string, std::string> c(10);
        c.upsert("foo", "bar");
        ASSERT_EQ(c.size(), 1);
    }

    /* ----------------------------------------------------------------------------
     * upsert / get
     * --------------------------------------------------------------------------*/

    TEST(LRUCache, getFromEmptyCache) {
        LRUCache<std::string, std::string> c(10);
        auto val = c.get("x");
        ASSERT_EQ(val.has_value(), false);
    }

    TEST(LRUCache, getExistingValue) {
        LRUCache<std::string, std::string> c(10);
        c.upsert("foo", "bar");
        auto val = c.get("foo");
        ASSERT_EQ(val, "bar");
    }

    TEST(LRUCache, getNonExistingValueFromNonEmptyCache) {
        LRUCache<std::string, std::string> c(10);
        c.upsert("foo", "bar");
        auto val = c.get("another");
        ASSERT_EQ(val.has_value(), false);
    }

    TEST(LRUCache, upsertOnZeroCapacityCache) {
        LRUCache<std::string, std::string> c(0);
        c.upsert("foo", "bar");
        auto val = c.get("foo");
        ASSERT_EQ(val.has_value(), false);
    }

    TEST(LRUCache, updateExistingValue) {
        LRUCache<std::string, std::string> c(1);
        c.upsert("foo", "bar");

        auto val = c.get("foo");
        ASSERT_EQ(val.value_or("error"), "bar");
        ASSERT_EQ(c.size(), 1);

        c.upsert("foo", "changed");
        val = c.get("foo");
        ASSERT_EQ(val.value_or("error"), "changed");
        ASSERT_EQ(c.size(), 1);
    }

    TEST(LRUCache, overwriteOldestWhenCapacityIsReached) {
        LRUCache<std::string, std::string> c(3);
        c.upsert("one", "eins");
        c.upsert("two", "zwei");
        c.upsert("three", "drei");

        ASSERT_EQ(c.size(), 3);
        ASSERT_EQ(c.get("one").value_or("error"), "eins");

        // exceed capacity
        c.upsert("another", "whatever");

        ASSERT_EQ(c.size(), 3);
        // Retrieving "one" makes it the most recent element thus
        // two will be the oldest one and thus replaced.
        ASSERT_EQ(c.get("two").has_value(), false);
        ASSERT_EQ(c.get("another").value(), "whatever");
    }

    /* ----------------------------------------------------------------------------
     * clear
     * --------------------------------------------------------------------------*/

    TEST(LRUCache, clearEmptyCache) {
        LRUCache<std::string, std::string> c(10);
        c.clear();
        ASSERT_EQ(c.size(), 0);
    }

    TEST(LRUCache, clearNonEmptyCache) {
        LRUCache<std::string, std::string> c(10);
        c.upsert("one", "eins");
        c.upsert("two", "zwei");
        c.upsert("three", "drei");
        ASSERT_EQ(c.size(), 3);
        c.clear();
        ASSERT_EQ(c.size(), 0);
    }

    /* ----------------------------------------------------------------------------
     * erase
     * --------------------------------------------------------------------------*/

    TEST(LRUCache, eraseFromEmptyCache) {
        LRUCache<std::string, std::string> c(10);
        ASSERT_EQ(c.erase("foo"), false);
        ASSERT_EQ(c.size(), 0);
    }

    TEST(LRUCache, eraseMissingFromNonEmptyCache) {
        LRUCache<std::string, std::string> c(10);
        c.upsert("one", "eins");
        ASSERT_EQ(c.erase("foo"), false);
        ASSERT_EQ(c.size(), 1);
        ASSERT_EQ(c.get("one").value_or("error"), "eins");
    }

    TEST(LRUCache, eraseFromNonEmptyCache) {
        LRUCache<std::string, std::string> c(10);
        c.upsert("one", "eins");
        ASSERT_EQ(c.erase("one"), true);
        ASSERT_EQ(c.size(), 0);
        ASSERT_EQ(c.get("one").value_or("empty"), "empty");
    }
}