net_pool/strategy/
h_strategy.rs

1use crate::backend::{Address, BackendState, BackendStates};
2use crate::utils::bytes_to_hash_code;
3use std::sync::RwLock;
4
5/// 普通hash策略
6
7pub struct HashStrategy(RwLock<BackendStates>);
8
9impl HashStrategy {
10    pub fn new() -> Self {
11        HashStrategy::default()
12    }
13}
14
15impl Default for HashStrategy {
16    fn default() -> Self {
17        HashStrategy(RwLock::new(BackendStates::new()))
18    }
19}
20
21impl super::LbStrategy for HashStrategy {
22    fn strategy(&self) -> super::Strategy {
23        super::Strategy::Hash
24    }
25
26    fn contain(&self, addr: &Address) -> bool {
27        let g = self.0.read().unwrap();
28        g.get_backend(addr).is_some()
29    }
30
31    fn add_backend(&self, id: Option<u32>, addr: Address) {
32        let mut g = self.0.write().unwrap();
33        g.add_backend(id, addr)
34    }
35
36    fn remove_backend(&self, addr: &Address) -> bool {
37        let mut g = self.0.write().unwrap();
38        g.remove_backend(&addr)
39    }
40
41    fn get_backend(&self, key: &str) -> Option<BackendState> {
42        let g = self.0.read().unwrap();
43        let bss = g.get_backends();
44        if bss.is_empty() {
45            return None;
46        }
47
48        let code = bytes_to_hash_code(key.as_bytes());
49        let idx = code % bss.len() as u64;
50        Some(bss[idx as usize].clone())
51    }
52
53    fn get_backends(&self) -> Vec<BackendState> {
54        let g = self.0.read().unwrap();
55        let bss = g.get_backends();
56        bss.iter().map(|bs| bs.clone()).collect()
57    }
58}