You can achieve high-performance, lock-free concurrent insertion by ensuring each thread only operates on a specific subset of the internal submaps. This is done by computing the hash of the key, determining its target submap index, and having the thread only proceed if that index belongs to its assigned range.
To implement this, use the subcnt() method to get the number of submaps and subidx(hashval) to determine the submap index for a given hash.
template <class HT>
void _fill_random_inner_mt(int64_t cnt, HT &hash, RSU &rsu)
{
constexpr int64_t num_threads = 8; // has to be a power of two
std::unique_ptr<std::thread> threads[num_threads];
auto thread_fn = [&hash, cnt, num_threads](int64_t thread_idx, RSU rsu) {
size_t modulo = hash.subcnt() / num_threads; // subcnt() returns the number of submaps
for (int64_t i=0; i<cnt; ++i)
{
unsigned int key = rsu.next(); // get next key to insert
size_t hashval = hash.hash(key); // compute its hash
size_t idx = hash.subidx(hashval); // compute the submap index for this hash
if (idx / modulo == thread_idx) // if the submap is suitable for this thread
{
hash.insert(typename HT::value_type(key, 0)); // insert the value
++(num_keys[thread_idx]); // increment count of inserted values
}
}
};
for (int64_t i=0; i<num_threads; ++i)
threads[i].reset(new std::thread(thread_fn, i, rsu));
for (int64_t i=0; i<cnt; ++i)
rsu.next();
for (int64_t i=0; i<cnt; ++i)
threads[i]->join();
}