use crate::{BalancingStrategy,Linker};
use tokio::sync::RwLock;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::ops::{DerefMut, Deref};
pub struct MinConn<K>{
list:RwLock<Vec<(K,AtomicUsize)>>
}
impl<K:Clone + Eq + Send + Sync > MinConn<K>{
pub fn new()->Self{
let list = RwLock::new(Vec::new());
Self{list}
}
}
#[async_trait::async_trait]
impl<K:Clone + Eq + Send + Sync > BalancingStrategy<K> for MinConn<K>{
async fn add(&self, k: K, n: usize) {
let mut writer = self.list.write().await;
let list = writer.deref_mut();
list.push((k,AtomicUsize::new(n)))
}
async fn remove(&self, k: K) {
let mut writer = self.list.write().await;
let list = writer.deref_mut();
for index in 0..list.len(){
if list[index].0 == k {
list.remove(index);
return;
}
}
}
async fn select(&self) -> Option<K> {
let reader = self.list.read().await;
let list = reader.deref();
if list.is_empty() {
return None;
}
let mut index = 0;
for i in 1..list.len(){
if list[i].1.load(Ordering::Relaxed) < list[index].1.load(Ordering::Relaxed) {
index = i
}
}
list[index].1.fetch_add(1,Ordering::Relaxed);
Some(list[index].0.clone())
}
}
#[async_trait::async_trait]
impl<K:Clone + Eq + Send + Sync > Linker<K> for MinConn<K>{
async fn acquire(&self, _k: K) {
}
async fn release(&self, k: K) {
let writer = self.list.read().await;
let list = writer.deref();
for index in 0..list.len(){
if list[index].0 == k {
list[index].1.fetch_sub(1,Ordering::Relaxed);
return;
}
}
}
}