mirror of
https://github.com/systemed/tilemaker
synced 2025-02-21 13:24:09 +01:00

On a 48-core machine, I still see lots of lock contention. AttributeStore:add is one place. Add a thread-local cache that can be consulted without taking the shared lock. The intuition here is that there are 1.3B objects, and 40M attribute sets. Thus, on average, an attribute set is reused 32 times. However, average is probably misleading -- the distribution is likely not uniform, e.g. the median attribute set is probably reused 1-2 times, and some exceptional attribute sets (e.g. `natural=tree` are reused thousands of times). For GB on a 16-core machine, this avoids 27M of 36M locks.
67 lines
1.7 KiB
C++
67 lines
1.7 KiB
C++
#include <iostream>
|
|
#include <algorithm>
|
|
#include "external/minunit.h"
|
|
#include "deque_map.h"
|
|
|
|
MU_TEST(test_deque_map) {
|
|
DequeMap<std::string> strs;
|
|
|
|
mu_check(strs.size() == 0);
|
|
mu_check(!strs.full());
|
|
mu_check(strs.find("foo") == -1);
|
|
mu_check(strs.add("foo") == 0);
|
|
mu_check(!strs.full());
|
|
mu_check(strs.find("foo") == 0);
|
|
mu_check(strs.size() == 1);
|
|
mu_check(strs.add("foo") == 0);
|
|
mu_check(strs.size() == 1);
|
|
mu_check(strs.add("bar") == 1);
|
|
mu_check(strs.size() == 2);
|
|
mu_check(strs.add("aardvark") == 2);
|
|
mu_check(strs.size() == 3);
|
|
mu_check(strs.add("foo") == 0);
|
|
mu_check(strs.add("bar") == 1);
|
|
mu_check(strs.add("quux") == 3);
|
|
mu_check(strs.size() == 4);
|
|
|
|
mu_check(strs.at(0) == "foo");
|
|
mu_check(strs[0] == "foo");
|
|
mu_check(strs.at(1) == "bar");
|
|
mu_check(strs[1] == "bar");
|
|
mu_check(strs.at(2) == "aardvark");
|
|
mu_check(strs[2] == "aardvark");
|
|
mu_check(strs.at(3) == "quux");
|
|
mu_check(strs[3] == "quux");
|
|
|
|
std::vector<std::string> rv;
|
|
for (std::string x : strs) {
|
|
rv.push_back(x);
|
|
}
|
|
mu_check(rv[0] == "aardvark");
|
|
mu_check(rv[1] == "bar");
|
|
mu_check(rv[2] == "foo");
|
|
mu_check(rv[3] == "quux");
|
|
|
|
DequeMap<std::string> boundedMap(1);
|
|
mu_check(!boundedMap.full());
|
|
mu_check(boundedMap.add("foo") == 0);
|
|
mu_check(boundedMap.add("foo") == 0);
|
|
mu_check(boundedMap.full());
|
|
mu_check(boundedMap.add("bar") == -1);
|
|
boundedMap.clear();
|
|
mu_check(!boundedMap.full());
|
|
mu_check(boundedMap.find("foo") == -1);
|
|
mu_check(boundedMap.add("bar") == 0);
|
|
mu_check(boundedMap.add("bar") == 0);
|
|
mu_check(boundedMap.full());
|
|
}
|
|
|
|
MU_TEST_SUITE(test_suite_deque_map) {
|
|
MU_RUN_TEST(test_deque_map);
|
|
}
|
|
|
|
int main() {
|
|
MU_RUN_SUITE(test_suite_deque_map);
|
|
MU_REPORT();
|
|
return MU_EXIT_CODE;
|
|
}
|