use rocketmq_common::common::consistenthash::ConsistentHashRouter;
use rocketmq_common::common::consistenthash::Node;
#[derive(Debug, Clone)]
struct ServerNode {
address: String,
}
impl ServerNode {
fn new(address: &str) -> Self {
Self {
address: address.to_string(),
}
}
}
impl Node for ServerNode {
fn get_key(&self) -> &str {
&self.address
}
}
fn main() {
println!("=== Consistent Hash Router Example ===\n");
let servers = vec![
ServerNode::new("192.168.1.1:8080"),
ServerNode::new("192.168.1.2:8080"),
ServerNode::new("192.168.1.3:8080"),
ServerNode::new("192.168.1.4:8080"),
];
let router = ConsistentHashRouter::new(servers.clone(), 150);
println!(
"Created hash ring with {} physical nodes and {} total virtual nodes\n",
servers.len(),
router.size()
);
println!("Routing keys to servers:");
let test_keys = vec![
"user:1001",
"user:1002",
"user:1003",
"order:2001",
"order:2002",
"product:3001",
"product:3002",
"session:4001",
];
for key in &test_keys {
if let Some(node) = router.route_node(key) {
println!(" {} -> {}", key, node.get_key());
}
}
println!("\n=== Consistency Test ===");
let key = "user:1001";
println!("Routing '{}' multiple times:", key);
for i in 1..=5 {
if let Some(node) = router.route_node(key) {
println!(" Attempt {}: {}", i, node.get_key());
}
}
println!("\n=== Distribution Statistics ===");
let mut distribution = std::collections::HashMap::new();
for i in 0..1000 {
let key = format!("key:{}", i);
if let Some(node) = router.route_node(&key) {
*distribution.entry(node.get_key().to_string()).or_insert(0) += 1;
}
}
println!("Distribution of 1000 keys:");
for (server, count) in distribution {
println!(" {}: {} keys ({:.1}%)", server, count, (count as f64 / 10.0));
}
println!("\n=== Adding a New Node ===");
let mut mutable_router = router.clone();
let new_server = ServerNode::new("192.168.1.5:8080");
mutable_router.add_node(new_server.clone(), 150);
println!(
"Added new server: {}. Total virtual nodes: {}",
new_server.get_key(),
mutable_router.size()
);
println!("\nKey redistribution after adding node:");
for key in &test_keys[0..4] {
let old_node = router.route_node(key).unwrap();
let new_node = mutable_router.route_node(key).unwrap();
if old_node.get_key() != new_node.get_key() {
println!(" {} moved from {} to {}", key, old_node.get_key(), new_node.get_key());
} else {
println!(" {} stayed on {}", key, old_node.get_key());
}
}
println!("\n=== Removing a Node ===");
let remove_server = servers[0].clone();
mutable_router.remove_node(&remove_server);
println!(
"Removed server: {}. Total virtual nodes: {}",
remove_server.get_key(),
mutable_router.size()
);
println!("\nKeys after node removal:");
for key in &test_keys {
if let Some(node) = mutable_router.route_node(key) {
println!(" {} -> {}", key, node.get_key());
}
}
}