use crate::backend::{Address, BackendState, BackendStates};
use crate::utils::bytes_to_hash_code;
use std::sync::RwLock;
pub struct HashStrategy(RwLock<BackendStates>);
impl HashStrategy {
pub fn new() -> Self {
HashStrategy::default()
}
}
impl Default for HashStrategy {
fn default() -> Self {
HashStrategy(RwLock::new(BackendStates::new()))
}
}
impl super::LbStrategy for HashStrategy {
fn strategy(&self) -> super::Strategy {
super::Strategy::Hash
}
fn contain(&self, addr: &Address) -> bool {
let g = self.0.read().unwrap();
g.get_backend(addr).is_some()
}
fn add_backend(&self, addr: Address) {
let mut g = self.0.write().unwrap();
g.add_backend(addr)
}
fn remove_backend(&self, addr: &Address) -> bool {
let mut g = self.0.write().unwrap();
g.remove_backend(&addr)
}
fn get_backend(&self, key: &str) -> Option<BackendState> {
let g = self.0.read().unwrap();
let bss = g.get_backends();
if bss.is_empty() {
return None;
}
let code = bytes_to_hash_code(key.as_bytes());
let idx = code % bss.len() as u64;
Some(bss[idx as usize].clone())
}
fn get_backends(&self) -> Vec<BackendState> {
let g = self.0.read().unwrap();
let bss = g.get_backends();
bss.iter().map(|bs| bs.clone()).collect()
}
}