use crate::line::EdgeEvent;
use crate::{Request, Result};
use std::cmp::max;
use std::time::Duration;
pub struct EdgeEventBuffer<'a> {
req: &'a Request,
event_u64_size: usize,
filled: usize,
read: usize,
buf: Vec<u64>,
}
impl EdgeEventBuffer<'_> {
pub(super) fn new(req: &Request, event_size: usize, capacity: usize) -> EdgeEventBuffer<'_> {
debug_assert!(event_size % 8 == 0);
let event_u64_size = event_size / 8;
EdgeEventBuffer {
req,
event_u64_size,
filled: 0,
read: 0,
buf: vec![0_u64; max(capacity, 1) * event_u64_size],
}
}
pub fn capacity(&self) -> usize {
self.buf.capacity() / self.event_u64_size
}
pub fn len(&self) -> usize {
(self.filled - self.read) / self.event_u64_size
}
pub fn is_empty(&self) -> bool {
self.read >= self.filled
}
pub fn has_event(&mut self) -> Result<bool> {
if self.read < self.filled {
return Ok(true);
}
self.req.has_edge_event()
}
pub fn read_event(&mut self) -> Result<EdgeEvent> {
if self.read < self.filled {
let evt_end = self.read + self.event_u64_size;
let evt = &self.buf[self.read..evt_end];
self.read = evt_end;
return self.req.edge_event_from_slice(evt);
}
self.read = 0;
self.filled = 0;
let n = self.req.read_edge_events_into_slice(&mut self.buf)?;
assert!(n > 0);
assert_eq!(n % (self.event_u64_size), 0);
self.filled = n;
self.read = self.event_u64_size;
self.req
.edge_event_from_slice(&self.buf[0..self.event_u64_size])
}
pub fn wait_event(&mut self, timeout: Duration) -> Result<EdgeEvent> {
self.req.wait_edge_event(timeout)?;
self.read_event()
}
}
impl Iterator for EdgeEventBuffer<'_> {
type Item = Result<EdgeEvent>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
Some(self.read_event())
}
}