use std::collections::HashSet;
use std::{cmp, fmt};
use rand::{self, seq::SliceRandom, Rng};
use crate::Contribution;
pub trait TransactionQueue<T>: fmt::Debug + Default + Extend<T> + Sync + Send {
fn is_empty(&self) -> bool;
fn choose<R: Rng>(&mut self, rng: &mut R, amount: usize, batch_size: usize) -> Vec<T>;
fn remove_multiple<'a, I>(&mut self, txs: I)
where
I: IntoIterator<Item = &'a T>,
T: 'a + Contribution;
}
impl<T> TransactionQueue<T> for Vec<T>
where
T: Clone + fmt::Debug + Sync + Send,
{
#[inline]
fn is_empty(&self) -> bool {
self.is_empty()
}
#[inline]
fn remove_multiple<'a, I>(&mut self, txs: I)
where
I: IntoIterator<Item = &'a T>,
T: 'a + Contribution,
{
let tx_set: HashSet<_> = txs.into_iter().collect();
self.retain(|tx| !tx_set.contains(tx));
}
#[inline]
fn choose<R: Rng>(&mut self, rng: &mut R, amount: usize, batch_size: usize) -> Vec<T> {
let limit = cmp::min(batch_size, self.len());
let sample = self[..limit].choose_multiple(rng, amount);
sample.cloned().collect()
}
}