kitt_score 0.1.0

Decision engine at the core of Project KITT — in-memory stateful matching with pluggable scoring backends.
Documentation
//! One shard of the location table.
//!
//! Holds a map `LocId -> Arc<Mutex<LocationState<T>>>` behind a `RwLock`.
//! The lock guards *insertion and removal*, not state mutation. Once a caller
//! clones the `Arc<Mutex<LocationState<T>>>`, they can drop the shard read
//! guard and work with the per-location mutex independently. This gives us
//! shard-level write coordination without blocking readers who only want a
//! handle.

use crate::location::state::LocationState;
use crate::LocId;
use ahash::AHashMap;
use parking_lot::{Mutex, RwLock};
use std::sync::Arc;

/// One shard of the location table.
#[derive(Default)]
pub struct Shard<T> {
    /// Map of location IDs to per-location mutex-guarded state.
    pub map: RwLock<AHashMap<LocId, Arc<Mutex<LocationState<T>>>>>,
}

impl<T> Shard<T> {
    /// Look up a location by ID, cloning the `Arc` handle.
    #[must_use]
    pub fn get(&self, id: LocId) -> Option<Arc<Mutex<LocationState<T>>>> {
        self.map.read().get(&id).cloned()
    }

    /// Insert a location state, returning the new `Arc` handle. Overwrites
    /// any existing entry for the same ID.
    pub fn insert(&self, id: LocId, state: LocationState<T>) -> Arc<Mutex<LocationState<T>>> {
        let arc = Arc::new(Mutex::new(state));
        self.map.write().insert(id, arc.clone());
        arc
    }

    /// Remove a location by ID. Returns `true` if the ID was present.
    pub fn remove(&self, id: LocId) -> bool {
        self.map.write().remove(&id).is_some()
    }

    /// Number of locations in this shard.
    #[allow(clippy::len_without_is_empty)]
    #[must_use]
    pub fn len(&self) -> usize {
        self.map.read().len()
    }
}