use rand::{RngExt, SeedableRng, rngs::SmallRng};
use crate::{
Collection,
storage::StorageBackend,
strategy::{Hooked, InstrumentedState, NoPad, Strategy},
};
#[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<()>>;
}