Expand description
An atomic, lock-free, hash map-like counter structure.
It uses Robin Hood hashing for collision resolution and supports concurrent access and modification of counters associated with keys. None of the operations require locks, making it suitable for high-performance scenarios.
§Features
- Atomic operations for incrementing and decrementing counters.
- Lock-free design for concurrent access.
- Robin Hood hashing for efficient collision resolution.
- Automatic resizing of the underlying storage when needed.
§Notes Before Use
- This is an experimental library and may not be suitable for production use yet. The API may change.
- It does not support shrinking of the underlying storage yet. However, since the structure uses a bucket of pointers, unused preallocated pointers only consume the null pointer size.
- Performance optimizations are still ongoing.
- Operations on atomics are always wrapping on overflow.
§Getting Started
To install this library, run the following command:
cargo add hypercounterThat’s it! To start using it, create a new HyperCounter instance:
use std::sync::atomic::{AtomicUsize, Ordering};
use hypercounter::HyperCounter;
let counter: HyperCounter<String, AtomicUsize> = HyperCounter::new();
counter.fetch_add("example_key".to_string(), 1, Ordering::Relaxed);
counter.fetch_sub("example_key".to_string(), 1, Ordering::Relaxed);Keys are automatically removed when their associated counter reaches zero. Neither inserts nor
removals are needed explicitly. If you want to remove a key manually, however, you can do so
using HyperCounter::swap() to swap the value with 0.
let previous_value = counter.swap("example_key".to_string(), 0, Ordering::Relaxed);§Supported Operations
The following atomic operations are supported:
HyperCounter::load(): Atomically loads the current value for a given key.HyperCounter::swap(): Atomically swaps the value for a given key.HyperCounter::fetch_add(): Atomically adds a value to the counter for a given key.HyperCounter::fetch_sub(): Atomically subtracts a value from the counter for a given key.HyperCounter::fetch_and(): Atomically performs a bitwise AND operation on the counter for a given key.HyperCounter::fetch_nand(): Atomically performs a bitwise NAND operation on the counter for a given key.HyperCounter::fetch_or(): Atomically performs a bitwise OR operation on the counter for a given key.HyperCounter::fetch_xor(): Atomically performs a bitwise XOR operation on the counter for a given key.HyperCounter::fetch_max(): Atomically sets the counter for a given key to the maximum of the current value and the provided value.HyperCounter::fetch_min(): Atomically sets the counter for a given key to the minimum of the current value and the provided value.
§Resizing
The HyperCounter automatically duplicates its internal storage when the load factor exceeds
75%. Its capacity starts at 8 and doubles with each expansion. Shrinking is not supported yet.
§Benchmarking
There’s a simple benchmark example included in the examples directory. You can run it using:
cargo run --example benchThis will execute a series of single-threaded benchmarks and print the operations per second for various scenarios.
Modules§
- map
- An atomic hash map implementation using Robin Hood hashing.