Hi everyone,
I had a lot of fun working on a fixed-capacity, open-addressing Hash Table using Robin Hood hashing. It uses sharded locking for writers and optimistic concurrency control (in particular seqlocks) for readers.
It works and passes all my tests on my x86_64. But I’m unsure if I’m missing a(or multiple) barriers in particular in the get/getBuffer function to make it truly correct.
Summarized it basically looks like this(kinda pseudo code)
retry: while(true) {
// Read version
version = ts.load(.acquire);
// Hashmap lookup logic and getting the final value
const k = slot.key;
const v = slot.value;
// Do I need a fence here?
// Validate version
const valid = version == ts.load(.acquire);
if (!valid) continue :retry;
}
The real code is of course more involved (ConcurrentHashTable.zig (24.7 KB)). I’ve written a lot of explanatory comments which could help (they were mostly for myself because else I’m forgetting the details…).
I unfortunately don’t have a machine with a weak memory model available to test it. Could anyone with an ARM or something run the tests for me? If you want you could also run the stress test by changing this to false:
test "multithreaded stress" {
if (true) { // change to false to run
return;
}
try stressTest(
1024 * 1024,
1024,
1_000_000, // maybe play with iterations
1024 * 1024,
8,
);
}
Thanks