use crate::Node;
#[derive(Debug, Clone)]
pub struct Finger {
pub(crate) _start: u64,
pub node: Node,
}
impl Finger {
pub const FINGER_TABLE_SIZE: u8 = 64;
pub(crate) fn finger_id(node_id: u64, index: u8) -> u64 {
Self::sized_finger_id(Self::FINGER_TABLE_SIZE, node_id, index)
}
pub(crate) fn sized_finger_id(size: u8, node_id: u64, index: u8) -> u64 {
if index == 0 {
return node_id;
}
let offset: u128 = 2_u128.pow((index - 1) as u32);
let power: u128 = 2_u128.pow(size as u32);
let id = (node_id as u128 + offset) % power;
id as u64
}
pub(crate) fn init_finger_table(node: Node) -> Vec<Self> {
Self::sized_finger_table(64, node)
}
fn sized_finger_table(size: u8, node: Node) -> Vec<Self> {
let mut fingers = Vec::with_capacity(size as usize);
for i in 1..(size + 1) {
let finger_id = Self::sized_finger_id(size, node.id.0, i);
fingers.push(Finger {
_start: finger_id,
node: node.clone(),
});
}
fingers
}
}
#[cfg(test)]
mod tests {
use crate::NodeId;
use super::*;
use std::net::SocketAddr;
#[test]
fn it_should_generate_finger_id() {
let node_id: u64 = 1;
assert_eq!(Finger::finger_id(node_id, 0), 1);
assert_eq!(Finger::finger_id(node_id, 1), 2);
assert_eq!(Finger::finger_id(node_id, 2), 3);
assert_eq!(Finger::finger_id(node_id, 3), 5);
assert_eq!(Finger::finger_id(node_id, 4), 9);
assert_eq!(Finger::finger_id(node_id, 5), 17);
assert_eq!(Finger::finger_id(node_id, 6), 33);
assert_eq!(Finger::finger_id(node_id, 7), 65);
assert_eq!(Finger::finger_id(node_id, 8), 129);
assert_eq!(Finger::finger_id(node_id, 9), 257);
assert_eq!(Finger::finger_id(node_id, 10), 513);
assert_eq!(Finger::finger_id(node_id, 11), 1025);
assert_eq!(Finger::finger_id(node_id, 12), 2049);
assert_eq!(Finger::finger_id(node_id, 13), 4097);
assert_eq!(Finger::finger_id(node_id, 14), 8193);
assert_eq!(Finger::finger_id(node_id, 15), 16385);
assert_eq!(Finger::finger_id(node_id, 32), 2147483649);
assert_eq!(Finger::finger_id(node_id, 64), 9223372036854775809);
assert_eq!(Finger::finger_id(node_id, 65), 1);
const M: u8 = 6;
assert_eq!(Finger::sized_finger_id(M, node_id, 0), 1);
assert_eq!(Finger::sized_finger_id(M, node_id, 1), 2);
assert_eq!(Finger::sized_finger_id(M, node_id, 2), 3);
assert_eq!(Finger::sized_finger_id(M, node_id, 3), 5);
assert_eq!(Finger::sized_finger_id(M, node_id, 4), 9);
assert_eq!(Finger::sized_finger_id(M, node_id, 5), 17);
assert_eq!(Finger::sized_finger_id(M, node_id, 6), 33);
assert_eq!(Finger::sized_finger_id(M, node_id, 7), 1);
}
#[test]
fn it_should_generate_finger_table() {
let node = Node::with_id(NodeId(1), SocketAddr::from(([127, 0, 0, 1], 42001)));
let fingers = Finger::init_finger_table(node.clone());
assert_eq!(fingers.len(), 64);
assert_eq!(fingers[0]._start, 2);
assert_eq!(fingers[1]._start, 3);
assert_eq!(fingers[2]._start, 5);
assert_eq!(fingers[3]._start, 9);
assert_eq!(fingers[4]._start, 17);
assert_eq!(fingers[5]._start, 33);
assert_eq!(fingers[15]._start, 32769);
assert_eq!(fingers[63]._start, 9223372036854775809);
let node = Node::with_id(NodeId(5), SocketAddr::from(([127, 0, 0, 1], 42001)));
let fingers = Finger::sized_finger_table(6, node);
assert_eq!(fingers.len(), 6);
assert_eq!(fingers[0]._start, 6);
assert_eq!(fingers[1]._start, 7);
assert_eq!(fingers[2]._start, 9);
assert_eq!(fingers[3]._start, 13);
assert_eq!(fingers[4]._start, 21);
assert_eq!(fingers[5]._start, 37);
}
}