crude_cache 0.1.0

A simple utility for good enough concurrent caching needs.
Documentation
use std::collections::HashMap;
use tokio::sync::{RwLock, RwLockWriteGuard, RwLockReadGuard};
use std::sync::Arc;
use std::hash::{Hash, Hasher};

#[derive(Default)]
pub struct ShardedMap<V: Send + Sync + 'static> {
    shards: Vec<Arc<RwLock<HashMap<String, V>>>>,
    num_shards: usize,
}

impl<V: Send + Sync> ShardedMap<V> {
    pub fn new(num_shards: usize) -> Self {
        let shards = (0..num_shards).map(|_| Arc::new(RwLock::new(HashMap::new()))).collect();

        ShardedMap { shards, num_shards }
    }

    fn get_shard(&self, key: &str) -> &Arc<RwLock<HashMap<String, V>>> {
        let mut hash = std::collections::hash_map::DefaultHasher::new();
        key.hash(&mut hash);
        let index = (hash.finish() % self.num_shards as u64) as usize;
        &self.shards[index]
    }

    pub async fn get_write_lock(&self, key: &str) -> RwLockWriteGuard<'_, HashMap<String, V>> {
        let shard = self.get_shard(key);
        shard.write().await
    }

    pub async fn get_read_lock(&self, key: &str) -> RwLockReadGuard<'_, HashMap<String, V>> {
        let shard = self.get_shard(key);
        shard.read().await
    }

    pub async fn insert(&self, key: String, value: V) {
        let shard = self.get_shard(&key);
        let mut map = shard.write().await;
        map.insert(key, value);
    }
}