Add WaitFreeHashMap::foreach.

This commit is contained in:
levlam 2022-08-04 15:08:18 +03:00
parent 779090f4dd
commit 6f46b50b4b
2 changed files with 37 additions and 8 deletions

View File

@ -108,6 +108,21 @@ class WaitFreeHashMap {
return get_storage(key).erase(key); return get_storage(key).erase(key);
} }
void foreach(std::function<void(const KeyT &key, ValueT &value)> callback) {
if (wait_free_storage_ == nullptr) {
for (auto &it : default_map_) {
callback(it.first, it.second);
}
return;
}
for (size_t i = 0; i < MAX_STORAGE_COUNT; i++) {
for (auto &it : wait_free_storage_->maps_[i]) {
callback(it.first, it.second);
}
}
}
size_t size() const { size_t size() const {
if (wait_free_storage_ == nullptr) { if (wait_free_storage_ == nullptr) {
return default_map_.size(); return default_map_.size();

View File

@ -24,6 +24,24 @@ TEST(WaitFreeHashMap, stress_test) {
return rnd() % 100000 + 1; return rnd() % 100000 + 1;
}; };
auto check = [&] {
ASSERT_EQ(reference.size(), map.size());
ASSERT_EQ(reference.empty(), map.empty());
if (reference.size() < 100) {
td::uint64 result = 0;
for (auto &it : reference) {
result += it.first * 101;
result += it.second;
}
map.foreach([&](const td::uint64 &key, td::uint64 &value) {
result -= key * 101;
result -= value;
});
ASSERT_EQ(0, result);
}
};
add_step(2000, [&] { add_step(2000, [&] {
auto key = gen_key(); auto key = gen_key();
auto value = rnd(); auto value = rnd();
@ -34,15 +52,13 @@ TEST(WaitFreeHashMap, stress_test) {
map[key] = value; map[key] = value;
} }
ASSERT_EQ(reference[key], map.get(key)); ASSERT_EQ(reference[key], map.get(key));
ASSERT_EQ(reference.size(), map.size()); check();
ASSERT_EQ(reference.empty(), map.empty());
}); });
add_step(200, [&] { add_step(200, [&] {
auto key = gen_key(); auto key = gen_key();
ASSERT_EQ(reference[key], map[key]); ASSERT_EQ(reference[key], map[key]);
ASSERT_EQ(reference.size(), map.size()); check();
ASSERT_EQ(reference.empty(), map.empty());
}); });
add_step(2000, [&] { add_step(2000, [&] {
@ -50,8 +66,7 @@ TEST(WaitFreeHashMap, stress_test) {
auto ref_it = reference.find(key); auto ref_it = reference.find(key);
auto ref_value = ref_it == reference.end() ? 0 : ref_it->second; auto ref_value = ref_it == reference.end() ? 0 : ref_it->second;
ASSERT_EQ(ref_value, map.get(key)); ASSERT_EQ(ref_value, map.get(key));
ASSERT_EQ(reference.size(), map.size()); check();
ASSERT_EQ(reference.empty(), map.empty());
}); });
add_step(500, [&] { add_step(500, [&] {
@ -59,8 +74,7 @@ TEST(WaitFreeHashMap, stress_test) {
size_t reference_erased_count = reference.erase(key); size_t reference_erased_count = reference.erase(key);
size_t map_erased_count = map.erase(key); size_t map_erased_count = map.erase(key);
ASSERT_EQ(reference_erased_count, map_erased_count); ASSERT_EQ(reference_erased_count, map_erased_count);
ASSERT_EQ(reference.size(), map.size()); check();
ASSERT_EQ(reference.empty(), map.empty());
}); });
td::RandomSteps runner(std::move(steps)); td::RandomSteps runner(std::move(steps));