Skip to content

Commit e08a7d9

Browse files
committed
Merge pull request #6561
7bd57bb Add limitedmap test (Casey Rodarmor) 8b06894 Disallow unlimited limited maps (Casey Rodarmor) fd2d862 Make limited map actually respect max size (Casey Rodarmor)
2 parents 0f0f323 + 7bd57bb commit e08a7d9

File tree

3 files changed

+113
-8
lines changed

3 files changed

+113
-8
lines changed

src/Makefile.test.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ BITCOIN_TESTS =\
5252
test/getarg_tests.cpp \
5353
test/hash_tests.cpp \
5454
test/key_tests.cpp \
55+
test/limitedmap_tests.cpp \
5556
test/main_tests.cpp \
5657
test/mempool_tests.cpp \
5758
test/miner_tests.cpp \

src/limitedmap.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ class limitedmap
2727
size_type nMaxSize;
2828

2929
public:
30-
limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; }
30+
limitedmap(size_type nMaxSizeIn)
31+
{
32+
assert(nMaxSizeIn > 0);
33+
nMaxSize = nMaxSizeIn;
34+
}
3135
const_iterator begin() const { return map.begin(); }
3236
const_iterator end() const { return map.end(); }
3337
size_type size() const { return map.size(); }
@@ -38,13 +42,12 @@ class limitedmap
3842
{
3943
std::pair<iterator, bool> ret = map.insert(x);
4044
if (ret.second) {
41-
if (nMaxSize && map.size() == nMaxSize) {
45+
if (map.size() > nMaxSize) {
4246
map.erase(rmap.begin()->second);
4347
rmap.erase(rmap.begin());
4448
}
4549
rmap.insert(make_pair(x.second, ret.first));
4650
}
47-
return;
4851
}
4952
void erase(const key_type& k)
5053
{
@@ -81,11 +84,11 @@ class limitedmap
8184
size_type max_size() const { return nMaxSize; }
8285
size_type max_size(size_type s)
8386
{
84-
if (s)
85-
while (map.size() > s) {
86-
map.erase(rmap.begin()->second);
87-
rmap.erase(rmap.begin());
88-
}
87+
assert(s > 0);
88+
while (map.size() > s) {
89+
map.erase(rmap.begin()->second);
90+
rmap.erase(rmap.begin());
91+
}
8992
nMaxSize = s;
9093
return nMaxSize;
9194
}

src/test/limitedmap_tests.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (c) 2012-2015 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include "limitedmap.h"
6+
7+
#include "test/test_bitcoin.h"
8+
9+
#include <boost/test/unit_test.hpp>
10+
11+
BOOST_FIXTURE_TEST_SUITE(limitedmap_tests, BasicTestingSetup)
12+
13+
BOOST_AUTO_TEST_CASE(limitedmap_test)
14+
{
15+
// create a limitedmap capped at 10 items
16+
limitedmap<int, int> map(10);
17+
18+
// check that the max size is 10
19+
BOOST_CHECK(map.max_size() == 10);
20+
21+
// check that it's empty
22+
BOOST_CHECK(map.size() == 0);
23+
24+
// insert (-1, -1)
25+
map.insert(std::pair<int, int>(-1, -1));
26+
27+
// make sure that the size is updated
28+
BOOST_CHECK(map.size() == 1);
29+
30+
// make sure that the new items is in the map
31+
BOOST_CHECK(map.count(-1) == 1);
32+
33+
// insert 10 new items
34+
for (int i = 0; i < 10; i++) {
35+
map.insert(std::pair<int, int>(i, i + 1));
36+
}
37+
38+
// make sure that the map now contains 10 items...
39+
BOOST_CHECK(map.size() == 10);
40+
41+
// ...and that the first item has been discarded
42+
BOOST_CHECK(map.count(-1) == 0);
43+
44+
// iterate over the map, both with an index and an iterator
45+
limitedmap<int, int>::const_iterator it = map.begin();
46+
for (int i = 0; i < 10; i++) {
47+
// make sure the item is present
48+
BOOST_CHECK(map.count(i) == 1);
49+
50+
// use the iterator to check for the expected key adn value
51+
BOOST_CHECK(it->first == i);
52+
BOOST_CHECK(it->second == i + 1);
53+
54+
// use find to check for the value
55+
BOOST_CHECK(map.find(i)->second == i + 1);
56+
57+
// update and recheck
58+
map.update(it, i + 2);
59+
BOOST_CHECK(map.find(i)->second == i + 2);
60+
61+
it++;
62+
}
63+
64+
// check that we've exhausted the iterator
65+
BOOST_CHECK(it == map.end());
66+
67+
// resize the map to 5 items
68+
map.max_size(5);
69+
70+
// check that the max size and size are now 5
71+
BOOST_CHECK(map.max_size() == 5);
72+
BOOST_CHECK(map.size() == 5);
73+
74+
// check that items less than 5 have been discarded
75+
// and items greater than 5 are retained
76+
for (int i = 0; i < 10; i++) {
77+
if (i < 5) {
78+
BOOST_CHECK(map.count(i) == 0);
79+
} else {
80+
BOOST_CHECK(map.count(i) == 1);
81+
}
82+
}
83+
84+
// erase some items not in the map
85+
for (int i = 100; i < 1000; i += 100) {
86+
map.erase(i);
87+
}
88+
89+
// check that the size is unaffected
90+
BOOST_CHECK(map.size() == 5);
91+
92+
// erase the remaining elements
93+
for (int i = 5; i < 10; i++) {
94+
map.erase(i);
95+
}
96+
97+
// check that the map is now empty
98+
BOOST_CHECK(map.empty());
99+
}
100+
101+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)