10 releases

Uses old Rust 2015

0.3.6 Aug 1, 2024
0.3.5 May 24, 2024
0.3.3 Nov 12, 2023
0.3.2 Jul 20, 2023
0.1.0 Nov 27, 2016

#69 in Caching

Download history 1671/week @ 2024-08-04 2085/week @ 2024-08-11 1591/week @ 2024-08-18 1931/week @ 2024-08-25 1676/week @ 2024-09-01 1736/week @ 2024-09-08 1257/week @ 2024-09-15 1462/week @ 2024-09-22 1332/week @ 2024-09-29 1507/week @ 2024-10-06 1957/week @ 2024-10-13 2084/week @ 2024-10-20 1807/week @ 2024-10-27 2149/week @ 2024-11-03 2360/week @ 2024-11-10 2625/week @ 2024-11-17

9,017 downloads per month
Used in 11 crates (7 directly)

MIT license

21KB
351 lines

HashRing

Build Status codecov crates.io docs.rs License

Documentation

A minimal implementation of consistent hashing as described in Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web. Clients can use the HashRing struct to add consistent hashing to their applications. HashRing's API consists of three methods: add, remove, and get for adding a node to the ring, removing a node from the ring, and getting the node responsible for the provided key.

Example

Below is a simple example of how an application might use HashRing to make use of consistent hashing. Since HashRing exposes only a minimal API clients can build other abstractions, such as virtual nodes, on top of it. The example below shows one potential implementation of virtual nodes on top of HashRing

use std::net::{IpAddr, SocketAddr};
use std::str::FromStr;

use hashring::HashRing;

#[derive(Debug, Copy, Clone, Hash, PartialEq)]
struct VNode {
    id: usize,
    addr: SocketAddr,
}

impl VNode {
    fn new(ip: &str, port: u16, id: usize) -> Self {
        let addr = SocketAddr::new(IpAddr::from_str(&ip).unwrap(), port);
        VNode {
            id: id,
            addr: addr,
        }
    }
}

impl ToString for VNode {
    fn to_string(&self) -> String {
        format!("{}|{}", self.addr, self.id)
    }
}

fn main() {
    let mut ring: HashRing<VNode> = HashRing::new();

    let mut nodes = vec![];
    nodes.push(VNode::new("127.0.0.1", 1024, 1));
    nodes.push(VNode::new("127.0.0.1", 1024, 2));
    nodes.push(VNode::new("127.0.0.2", 1024, 1));
    nodes.push(VNode::new("127.0.0.2", 1024, 2));
    nodes.push(VNode::new("127.0.0.2", 1024, 3));
    nodes.push(VNode::new("127.0.0.3", 1024, 1));

    for node in nodes {
        ring.add(node);
    }

    println!("{:?}", ring.get(&"foo"));
    println!("{:?}", ring.get(&"bar"));
    println!("{:?}", ring.get(&"baz"));
}

Dependencies

~54KB