#[derive(Debug, PartialEq)]
pub struct Inflights {
start: usize,
count: usize,
buffer: Vec<u64>,
}
impl Clone for Inflights {
fn clone(&self) -> Self {
let mut buffer = self.buffer.clone();
buffer.reserve(self.buffer.capacity() - self.buffer.len());
Inflights {
start: self.start,
count: self.count,
buffer,
}
}
}
impl Inflights {
pub fn new(cap: usize) -> Inflights {
Inflights {
buffer: Vec::with_capacity(cap),
start: 0,
count: 0,
}
}
#[inline]
pub fn full(&self) -> bool {
self.count == self.cap()
}
#[inline]
pub fn cap(&self) -> usize {
self.buffer.capacity()
}
pub fn add(&mut self, inflight: u64) {
if self.full() {
panic!("cannot add into a full inflights")
}
let mut next = self.start + self.count;
if next >= self.cap() {
next -= self.cap();
}
assert!(next <= self.buffer.len());
if next == self.buffer.len() {
self.buffer.push(inflight);
} else {
self.buffer[next] = inflight;
}
self.count += 1;
}
pub fn free_to(&mut self, to: u64) {
if self.count == 0 || to < self.buffer[self.start] {
return;
}
let mut i = 0usize;
let mut idx = self.start;
while i < self.count {
if to < self.buffer[idx] {
break;
}
idx += 1;
if idx >= self.cap() {
idx -= self.cap();
}
i += 1;
}
self.count -= i;
self.start = idx;
}
#[inline]
pub fn free_first_one(&mut self) {
let start = self.buffer[self.start];
self.free_to(start);
}
#[inline]
pub fn reset(&mut self) {
self.count = 0;
self.start = 0;
}
}
#[cfg(test)]
mod tests {
use super::Inflights;
#[test]
fn test_inflight_add() {
let mut inflight = Inflights::new(10);
for i in 0..5 {
inflight.add(i);
}
let wantin = Inflights {
start: 0,
count: 5,
buffer: vec![0, 1, 2, 3, 4],
};
assert_eq!(inflight, wantin);
for i in 5..10 {
inflight.add(i);
}
let wantin2 = Inflights {
start: 0,
count: 10,
buffer: vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
};
assert_eq!(inflight, wantin2);
let mut inflight2 = Inflights::new(10);
inflight2.start = 5;
inflight2.buffer.extend_from_slice(&[0, 0, 0, 0, 0]);
for i in 0..5 {
inflight2.add(i);
}
let wantin21 = Inflights {
start: 5,
count: 5,
buffer: vec![0, 0, 0, 0, 0, 0, 1, 2, 3, 4],
};
assert_eq!(inflight2, wantin21);
for i in 5..10 {
inflight2.add(i);
}
let wantin22 = Inflights {
start: 5,
count: 10,
buffer: vec![5, 6, 7, 8, 9, 0, 1, 2, 3, 4],
};
assert_eq!(inflight2, wantin22);
}
#[test]
fn test_inflight_free_to() {
let mut inflight = Inflights::new(10);
for i in 0..10 {
inflight.add(i);
}
inflight.free_to(4);
let wantin = Inflights {
start: 5,
count: 5,
buffer: vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
};
assert_eq!(inflight, wantin);
inflight.free_to(8);
let wantin2 = Inflights {
start: 9,
count: 1,
buffer: vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
};
assert_eq!(inflight, wantin2);
for i in 10..15 {
inflight.add(i);
}
inflight.free_to(12);
let wantin3 = Inflights {
start: 3,
count: 2,
buffer: vec![10, 11, 12, 13, 14, 5, 6, 7, 8, 9],
};
assert_eq!(inflight, wantin3);
inflight.free_to(14);
let wantin4 = Inflights {
start: 5,
count: 0,
buffer: vec![10, 11, 12, 13, 14, 5, 6, 7, 8, 9],
};
assert_eq!(inflight, wantin4);
}
#[test]
fn test_inflight_free_first_one() {
let mut inflight = Inflights::new(10);
for i in 0..10 {
inflight.add(i);
}
inflight.free_first_one();
let wantin = Inflights {
start: 1,
count: 9,
buffer: vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
};
assert_eq!(inflight, wantin);
}
}