use super::*;
pub(super) struct RedisEntry {
pub(super) url: String,
pub(super) conn: redis::Connection,
}
pub(super) struct RedisRegistry {
pub(super) entries: indexmap::IndexMap<u64, RedisEntry>,
pub(super) cap: usize,
}
impl RedisRegistry {
pub(super) fn with_capacity(cap: usize) -> Self {
Self { entries: indexmap::IndexMap::new(), cap }
}
pub(super) fn insert(&mut self, handle: u64, entry: RedisEntry) {
if self.entries.len() >= self.cap {
self.entries.shift_remove_index(0);
}
self.entries.insert(handle, entry);
}
pub(super) fn touch_get_mut(&mut self, handle: u64) -> Option<&mut RedisEntry> {
let idx = self.entries.get_index_of(&handle)?;
self.entries.move_index(idx, self.entries.len() - 1);
self.entries.get_mut(&handle)
}
pub(super) fn get_url(&self, handle: u64) -> Option<String> {
self.entries.get(&handle).map(|e| e.url.clone())
}
pub(super) fn remove(&mut self, handle: u64) {
self.entries.shift_remove(&handle);
}
}
pub(super) fn redis_registry() -> &'static Mutex<RedisRegistry> {
static REGISTRY: OnceLock<Mutex<RedisRegistry>> = OnceLock::new();
REGISTRY.get_or_init(|| Mutex::new(RedisRegistry::with_capacity(MAX_REDIS_HANDLES)))
}
pub(super) const MAX_REDIS_HANDLES: usize = 256;
pub(super) fn next_redis_handle() -> u64 {
static COUNTER: AtomicU64 = AtomicU64::new(1);
COUNTER.fetch_add(1, Ordering::SeqCst)
}
pub(super) fn expect_redis_handle(v: Option<&Value>) -> Result<u64, String> {
match v {
Some(Value::Int(n)) if *n >= 0 => Ok(*n as u64),
Some(other) => Err(format!("expected ConnRedis (Int), got {other:?}")),
None => Err("missing ConnRedis argument".into()),
}
}