#hash-ring #consistent-hashing #ring #consistent #hash #distributed #virtual-nodes

hulahoop

An efficient consistent hash ring implementation supporting virtual nodes

2 unstable releases

0.2.0 Oct 29, 2022
0.1.0 Oct 8, 2022

#1865 in Algorithms

MIT/Apache

27KB
427 lines

Hulahoop GitHub Workflow Status docs.rs Crates.io

A fast and efficient consistent hashing implementation, with support for virtual nodes.


Usage

    use hulahoop::HashRing;

    let mut ring: HashRing<&str, _> = HashRing::default();

    // Nodes only need to implement Hash
    // Provide a weight to define the number of virtual nodes
    ring.insert("10.0.0.1:1234", 10);
    ring.insert("10.0.0.2:1234", 10);

    // Keys also only need to implement Hash
    assert_eq!(ring.get("Some key"), Some(&"10.0.0.1:1234"));
    assert_eq!(ring.get("Another key"), Some(&"10.0.0.2:1234"));

    ring.remove(&"10.0.0.2:1234");

    assert_eq!(ring.get("Some key"), Some(&"10.0.0.1:1234"));
    assert_eq!(ring.get("Another key"), Some(&"10.0.0.1:1234"));

HashRing uses Arc under the hood to allocate memory only per node and not for every virtual node added via the weight parameter.

The Hashring is Send + Sync.


Hashers

Per default, hulahoop uses std::collections::hash_map::DefaultHasher to hash values.

Custom hashers can be used with the HashRing::with_hasher() method:

    use rustc_hash::FxHasher;
    let mut ring: HashRing<&str, _> = HashRing::with_hasher(BuildHasherDefault::<FxHasher>::default());

For convenience, the faster hasher FxHasher can be used by activating the fxhash feature of this crate.


Benchmarks

DefaultHasher FxHasher (feature=fxhash)
Get (key length = 10) 13ns 8ns
Get (key length = 100) 31ns 12ns
Get (key length = 1000) 305ns 137ns
Add (weight = 1) 290ns 210ns
Add (weight = 10) 1.4us 1.0us
Add (weight = 100) 17.0us 14.3us

License

This project is licensed optionally under either:

Dependencies