kasino 0.1.0

Framework for implementing sharded concurrent datastructures.
Documentation
use rand::{RngExt, SeedableRng, rngs::SmallRng};

use crate::{
    Collection,
    storage::StorageBackend,
    strategy::{Hooked, InstrumentedState, NoPad, Strategy},
};

/// A random scheduler.
///
/// This scheduler does not promise a bound on rank error or delay.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RandomAccess<R = SmallRng> {
    rng: R,
}

impl<S> Default for RandomAccess<S>
where
    S: SeedableRng,
{
    #[inline]
    fn default() -> Self {
        Self {
            rng: S::seed_from_u64(Default::default()),
        }
    }
}

impl<Q: Collection, S: RngExt + SeedableRng> Strategy<Q> for RandomAccess<S> {
    type Gambler = Self;

    #[inline]
    fn choose_offer_arm(
        &self,
        state: &impl StorageBackend<<Self::Gambler as Hooked>::Stake>,
        gambler: &mut Self::Gambler,
    ) -> usize {
        gambler.rng.random_range(..state.len())
    }

    #[inline]
    fn choose_poll_arm(
        &self,
        state: &impl StorageBackend<<Self::Gambler as Hooked>::Stake>,
        gambler: &mut Self::Gambler,
    ) -> usize {
        gambler.rng.random_range(..state.len())
    }

    #[inline]
    fn fork_gambler(&self, gambler: &mut Self::Gambler) -> Self::Gambler {
        Self {
            rng: gambler.rng.fork(),
        }
    }

    #[inline]
    fn create_gambler(&self) -> Self::Gambler {
        Self {
            rng: S::seed_from_u64(Default::default()),
        }
    }
}

impl<S> Hooked for RandomAccess<S> {
    type Stake = NoPad<InstrumentedState<()>>;
}