use std::collections::VecDeque;
use super::part::Part;
#[derive(Debug)]
pub struct SeekWindow {
parts: VecDeque<Part>,
max_size: usize,
current_size: usize,
}
impl SeekWindow {
pub fn new(max_size: usize) -> Self {
assert!(max_size > 0);
SeekWindow {
parts: VecDeque::new(),
max_size,
current_size: 0,
}
}
pub fn push(&mut self, part: Part) {
if part.len() > self.max_size {
self.clear();
return;
}
while self.max_size - self.current_size < part.len() {
let p = self
.parts
.pop_front()
.expect("window is non-empty if current size is non-zero");
self.current_size -= p.len();
}
self.current_size += part.len();
self.parts.push_back(part);
}
pub fn read_back(&mut self, mut length: usize) -> Option<Vec<Part>> {
if length > self.current_size {
return None;
}
let mut result = VecDeque::new();
loop {
if length == 0 {
break;
}
let mut part = self.parts.pop_back().expect("we checked that current_size >= length");
if part.len() > length {
let back = part.split_off(part.len() - length);
self.parts.push_back(part);
part = back;
}
length -= part.len();
self.current_size -= part.len();
result.push_front(part);
}
Some(result.into())
}
pub fn clear(&mut self) {
self.parts.drain(..);
self.current_size = 0;
}
pub fn max_size(&self) -> usize {
self.max_size
}
}