greg7mdp / parallel-hashmap

A family of header-only, very fast and memory-friendly hashmap and btree containers.
https://greg7mdp.github.io/parallel-hashmap/
Apache License 2.0
2.47k stars 234 forks source link

Add try_emplace_p extension method #206

Closed ecatmur closed 1 year ago

ecatmur commented 1 year ago

Iterators are invalidated by concurrent insertion (rehash, resize, etc...) whereas for node-based containers, pointers are only invalidated by erase/clear.

e.g. this program causes a data race (read vs. reallocate) w/ tsan (g++ 11.4.0-1ubuntu1~22.04 -fsanitize=thread):

#include <parallel_hashmap/phmap.h>
#include <thread>
#include <mutex>
int main() {
    phmap::parallel_node_hash_map<int, int, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, int>>, 4, std::mutex> map;
    std::thread t1([&] { for (int i = 0; i != 10; ++i) ++map.try_emplace(i, i).first->second; });
    std::thread t2([&] { for (int i = 10; i != 20; ++i) ++map.try_emplace(i, i).first->second; });
    t1.join();
    t2.join();
}

Applying this PR and changing try_emplace to try_emplace_p fixes it.