File: parallel_hash_map_test.cc

package info (click to toggle)
parallel-hashmap 1.4.1%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,872 kB
  • sloc: cpp: 20,492; ansic: 1,114; python: 492; makefile: 85; haskell: 56; perl: 43; sh: 23
file content (169 lines) | stat: -rw-r--r-- 5,313 bytes parent folder | download
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#ifndef THIS_HASH_MAP
    #define THIS_HASH_MAP  parallel_flat_hash_map
    #define THIS_TEST_NAME ParallelFlatHashMap
#endif

#include "flat_hash_map_test.cc"

namespace phmap {
namespace priv {
namespace {

TEST(THIS_TEST_NAME, Swap) {
    using Map = ThisMap<int, int>;
    using MapB = ThisMap_NullMutex<int, int>;
    
    Map t;
    EXPECT_TRUE(t.find(0) == t.end());
    auto res = t.emplace(0, 1);
    EXPECT_TRUE(res.second);
    EXPECT_EQ(1, t.size());
    MapB u;
    t.swap(u);
    EXPECT_EQ(0, t.size());
    EXPECT_EQ(1, u.size());
    EXPECT_TRUE(t.find(0) == t.end());
    EXPECT_TRUE(u[0] == 1);
}


TEST(THIS_TEST_NAME, IfContains) {
    // ----------------
    // test if_contains
    // ----------------

    using Map = ThisMap<int, int>;
    Map m = { {1, 7}, {2, 9} };
    const Map& const_m(m);
    
    auto val = 0; 
    auto get_value = [&val](const Map::value_type& v) { val = v.second; };
    EXPECT_TRUE(const_m.if_contains(2, get_value));
    EXPECT_EQ(val, 9);

    EXPECT_FALSE(m.if_contains(3, get_value));
}

TEST(THIS_TEST_NAME, ModifyIf) {
    // --------------
    // test modify_if
    // --------------
    using Map = ThisMap<int, int>;
    Map m = { {1, 7}, {2, 9} };

    auto set_value = [](Map::value_type& v) { v.second = 11; };
    EXPECT_TRUE(m.modify_if(2, set_value));
    EXPECT_EQ(m[2], 11);

    EXPECT_FALSE(m.modify_if(3, set_value)); // because m[3] does not exist
}

TEST(THIS_TEST_NAME, TryEmplaceL) {
    // ------------------
    // test try_emplace_l
    // ------------------
    using Map = ThisMap<int, int>;
    Map m = { {1, 7}, {2, 9} };

    // overwrite an existing value
    m.try_emplace_l(2, [](Map::value_type& v) { v.second = 5; });
    EXPECT_EQ(m[2], 5);

    // insert a value that is not already present. Will be default initialised to 0 and lambda not called
    m.try_emplace_l(3, 
                    [](Map::value_type& v) { v.second = 6; }, // called only when key was already present
                    1);                    // argument to construct new value is key not present
    EXPECT_EQ(m[3], 1);
    
    // insert a value that is not already present, provide argument to value-construct it
    m.try_emplace_l(4, 
                    [](Map::value_type& ) {}, // called only when key was already present
                    999);                     // argument to construct new value is key not present

    EXPECT_EQ(m[4], 999);
}

TEST(THIS_TEST_NAME, LazyEmplaceL) {
    // --------------------
    // test lazy_emplace_l
    // --------------------
    using Map = ThisMap<int, int>;
    Map m = { {1, 7}, {2, 9} };
 
    // insert a value that is not already present.
    // right now m[5] does not exist
    m.lazy_emplace_l(5, 
                     [](Map::value_type& v) { v.second = 6; },           // called only when key was already present
                     [](const Map::constructor& ctor) { ctor(5, 13); }); // construct value_type in place when key not present 
    EXPECT_EQ(m[5], 13);

    // change a value that is present. Currently m[5] == 13
    m.lazy_emplace_l(5, 
                     [](Map::value_type& v) { v.second = 6; },           // called only when key was already present
                     [](const Map::constructor& ctor) { ctor(5, 13); }); // construct value_type in place when key not present
    EXPECT_EQ(m[5], 6);
}

TEST(THIS_TEST_NAME, EraseIf) {
    // -------------
    // test erase_if
    // -------------
    using Map = ThisMap<int, int>;
    Map m = { {1, 7}, {2, 9}, {5, 6} };

    EXPECT_EQ(m.erase_if(9, [](Map::value_type& v) { assert(0); return v.second == 12; }), false); // m[9] not present - lambda not called
    EXPECT_EQ(m.erase_if(5, [](Map::value_type& v) { return v.second == 12; }), false);            // m[5] == 6, so erase not performed
    EXPECT_EQ(m[5], 6);
    EXPECT_EQ(m.erase_if(5, [](Map::value_type& v) { return v.second == 6; }), true);              // lambda returns true, so m[5] erased
    EXPECT_EQ(m[5], 0);
}

TEST(THIS_TEST_NAME, ForEach) {
    // -------------
    // test for_each
    // -------------
    using Map = ThisMap<int, int>;
    Map m = { {1, 7}, {2, 8}, {5, 11} };

    // increment all values by 1
    m.for_each_m([](Map::value_type &pair) {  ++pair.second; });

    int counter = 0;
    m.for_each([&counter](const Map::value_type &pair) {
            ++counter;
            EXPECT_EQ(pair.first + 7, pair.second);
        });
    EXPECT_EQ(counter, 3);
    
    counter = 0;
    for (size_t i=0; i<m.subcnt(); ++i) {
        m.with_submap(i, [&](const Map::EmbeddedSet& set) {
            for (auto& p : set) {
                ++counter;
                EXPECT_EQ(p.first + 7, p.second);
            }
        });
    }
    EXPECT_EQ(counter, 3);
}

TEST(THIS_TEST_NAME, EmplaceSingle) {
    // --------------------
    // test emplace_single
    // --------------------
    using Map = ThisMap<int, int>;
    Map m = { {1, 4}, {11, 4} };
 
    // emplace_single insert a value if not already present, else removes it
    for (int i=0; i<12; ++i)
        m.emplace_single(i, [i](const Map::constructor& ctor) { ctor(i, 4); });
    EXPECT_EQ(m.count(0), 1);
    EXPECT_EQ(m.count(1), 0);
    EXPECT_EQ(m.count(2), 1);
    EXPECT_EQ(m.count(11), 0);
}


}  // namespace
}  // namespace priv
}  // namespace phmap