59 lines
2.0 KiB
Markdown
59 lines
2.0 KiB
Markdown
# HashMapConcurrent
|
|
|
|
A thread-safe, fixed-capacity, open-addressing hash map for Zig.
|
|
|
|
This implementation combines *Robin Hood hashing* (to minimize probe lengths) with *Sequence
|
|
Locking* (to provide wait-free-like read performance) and *Shard-Level Locking* for writers.
|
|
Deletions use *Backward-Shift* to maintain table compactness without the performance degradation
|
|
of tombstones.
|
|
|
|
## Quick Start
|
|
|
|
```zig
|
|
const std = @import("std");
|
|
const HashMap = @import("hashmap_concurrent.zig").AutoHashMapConcurrent;
|
|
|
|
pub fn main() !void {
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const allocator = gpa.allocator();
|
|
|
|
// capacity must be a power of two.
|
|
// num_shards balances writer contention vs reader retry probability.
|
|
var map = try HashMap(u64, u64).init(allocator, 1024, 64);
|
|
defer map.deinit(allocator);
|
|
|
|
map.put(42, 1337);
|
|
const val = map.get(42);
|
|
std.debug.print("Value: {d}\n", .{val});
|
|
}
|
|
```
|
|
|
|
## Iteration
|
|
|
|
There are two ways to iterate over entries, depending on your consistency requirements:
|
|
|
|
`lockingIterator()`: Uses *Lock Coupling* to prevent elements from being missed or seen twice if they
|
|
are moved across shard boundaries during iteration. Due to the locking you must call `it.deinit()`
|
|
if you break or return from the loop early to release the held shard lock.
|
|
|
|
`approximateIterator()`: Optimistic and approximate because it just uses *Sequence Locks*. It may
|
|
miss entries or see the same entry twice if concurrent writers move elements. It's Lock-free and
|
|
safe to use on const references. Safe to break early without cleanup.
|
|
|
|
## Usage & Safety
|
|
|
|
For a detailed explanation of the concurrency model, deadlock safety, and memory reclamation, please
|
|
refer to the documentation at the top of `hashmap_concurrent.zig`.
|
|
|
|
## License
|
|
|
|
BSD 3-Clause. See `hashmap_concurrent.zig` and `LICENSE` for the full text.
|
|
|
|
## Benchmark Results
|
|
|
|
Done with 100 million iterations on a quiet AMD Ryzen AI 5 340.
|
|
|
|

|
|
|
|

|