Skip to content

Commit

Permalink
add support for iterators
Browse files Browse the repository at this point in the history
Adds the ability to iterate over nodes in the ring. This helps
users attempting to access the internal ring for serialization purposes
and help with needs for replication where a user would want to access
a node that neighbors the node responsible for the key
  • Loading branch information
connormullett committed Jul 14, 2023
1 parent fd56df7 commit 10cbd7e
Showing 1 changed file with 47 additions and 1 deletion.
48 changes: 47 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl BuildHasher for DefaultHashBuilder {
// Node is an internal struct used to encapsulate the nodes that will be added and
// removed from `HashRing`
#[derive(Debug)]
struct Node<T> {
pub struct Node<T> {
key: u64,
node: T,
}
Expand Down Expand Up @@ -215,6 +215,30 @@ impl<T: Hash, S: BuildHasher> HashRing<T, S> {
}
}

pub struct HashRingIterator<T> {
ring: std::vec::IntoIter<T>,
}

impl<T> Iterator for HashRingIterator<T> {
type Item = T;

fn next(&mut self) -> Option<Self::Item> {
self.ring.next()
}
}

impl<T: Clone> IntoIterator for HashRing<T> {
type Item = Node<T>;

type IntoIter = HashRingIterator<Node<T>>;

fn into_iter(self) -> Self::IntoIter {
HashRingIterator {
ring: self.ring.into_iter(),
}
}
}

// An internal function for converting a reference to a hashable type into a `u64` which
// can be used as a key in the hash ring.
fn get_key<S, T>(hash_builder: &S, input: T) -> u64
Expand Down Expand Up @@ -339,4 +363,26 @@ mod tests {
println!("{:?}", nodes);
assert!(nodes.iter().all(|x| *x != 0));
}

#[test]
fn into_iter() {
let mut ring: HashRing<VNode> = HashRing::new();

assert_eq!(ring.get(&"foo"), None);

let vnode1 = VNode::new("127.0.0.1", 1024, 1);
let vnode2 = VNode::new("127.0.0.1", 1024, 2);
let vnode3 = VNode::new("127.0.0.2", 1024, 1);

ring.add(vnode1);
ring.add(vnode2);
ring.add(vnode3);

let mut iter = ring.into_iter();

assert_eq!(Some(vnode1), iter.next().and_then(|n| Some(n.node)));
assert_eq!(Some(vnode3), iter.next().and_then(|n| Some(n.node)));
assert_eq!(Some(vnode2), iter.next().and_then(|n| Some(n.node)));
assert_eq!(None, iter.next());
}
}

0 comments on commit 10cbd7e

Please sign in to comment.