use std::collections::VecDeque;
use std::sync::Mutex;
use crate::bench_harness::{BenchQueue, BenchQueueOps, LogQueue, LogQueueOps, LogRecord};
pub struct MutexQueue<T> {
inner: Mutex<VecDeque<T>>,
}
impl<T> MutexQueue<T> {
pub fn new() -> Self {
Self {
inner: Mutex::new(VecDeque::new()),
}
}
}
impl<T> Default for MutexQueue<T> {
fn default() -> Self {
Self::new()
}
}
impl BenchQueueOps for MutexQueue<u64> {
fn try_send_value(&self, value: u64) -> bool {
self.inner.lock().expect("mutex poisoned").push_back(value);
true
}
fn send_batch(&self, base: u64, offsets: std::ops::Range<usize>) {
let mut guard = self.inner.lock().expect("mutex poisoned");
guard.extend(offsets.map(|offset| base + offset as u64));
}
fn try_recv_value(&self) -> Option<u64> {
self.inner.lock().expect("mutex poisoned").pop_front()
}
fn try_recv_batch(&self, request_size: usize) -> usize {
let mut guard = self.inner.lock().expect("mutex poisoned");
let available = guard.len().min(request_size);
guard.drain(..available).count()
}
}
impl BenchQueue for MutexQueue<u64> {
fn new_queue() -> std::sync::Arc<Self> {
std::sync::Arc::new(Self::new())
}
}
impl LogQueueOps for MutexQueue<LogRecord> {
fn send_log(&self, record: LogRecord) {
self.inner.lock().expect("mutex poisoned").push_back(record);
}
fn try_recv_log(&self) -> Option<LogRecord> {
self.inner.lock().expect("mutex poisoned").pop_front()
}
}
impl LogQueue for MutexQueue<LogRecord> {
fn new_log_queue() -> std::sync::Arc<Self> {
std::sync::Arc::new(Self::new())
}
}