use crate::av::frame::Frame; use std::collections::HashMap; use std::fmt::{Debug, Error, Formatter}; use std::hash::Hash; pub struct SortedBuffer { lowest_value: Option, sorted_keys: Vec, items: HashMap, open: bool, buffer_size: usize, } impl Debug for SortedBuffer { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { f.debug_struct("SortedBuffer") .field("lowest_value", &self.lowest_value) .field("sorted_keys", &self.sorted_keys) .field("items", &self.items) .field("open", &self.open) .field("buffer_size", &self.buffer_size) .finish() } } pub type SortedFrameBuffer = SortedBuffer; impl SortedFrameBuffer { pub fn insert_frame(&mut self, frame: Frame) -> bool { self.insert(frame.pts(), frame) } } impl Default for SortedBuffer { fn default() -> Self { SortedBuffer { lowest_value: None, sorted_keys: vec![], items: Default::default(), open: true, buffer_size: 32, } } } impl SortedBuffer { pub fn new() -> Self { Default::default() } pub fn with_buffer_size(buffer_size: usize) -> Self { let mut buffer: Self = Default::default(); buffer.buffer_size = buffer_size; buffer } pub fn insert(&mut self, key: K, item: V) -> bool { if self.items.len() >= self.buffer_size && self.lowest_value.map(|it| it > key).unwrap_or(false) { return false; } self.insert_key(key); self.items.insert(key, item); true } fn insert_key(&mut self, key: K) { if self.lowest_value.map(|it| it > key).unwrap_or(true) { self.lowest_value = Some(key) } let mut i = 0; for entry in &self.sorted_keys { if key < *entry { break; } i += 1; } self.sorted_keys.insert(i, key); } pub fn close(&mut self) { self.open = false; } pub fn pop_first(&mut self) -> Option { if self.sorted_keys.len() == 0 || (self.open && self.buffer_size >= self.items.len()) { return None; } let first = self.sorted_keys.remove(0); if let Some(new_first) = self.sorted_keys.get(0).copied() { self.lowest_value = Some(new_first); } self.items.remove(&first) } pub fn len(&self) -> usize { self.sorted_keys.len() } } #[cfg(test)] mod test { use crate::utils::SortedBuffer; #[test] fn test_sorted_buffer() { let mut buffer = SortedBuffer::with_buffer_size(5); assert!(buffer.insert(2, 2)); assert!(buffer.insert(1, 1)); assert!(buffer.insert(3, 3)); assert!(buffer.insert(4, 4)); assert!(buffer.insert(5, 5)); assert!(!buffer.insert(0, 0)); assert_eq!(buffer.len(), 5); assert!(buffer.insert(6, 6)); assert_eq!(buffer.len(), 6); assert_eq!(buffer.pop_first(), Some(1)); assert_eq!(buffer.pop_first(), None); assert_eq!(buffer.len(), 5); buffer.close(); assert_eq!(buffer.pop_first(), Some(2)); assert_eq!(buffer.pop_first(), Some(3)); assert_eq!(buffer.pop_first(), Some(4)); assert_eq!(buffer.pop_first(), Some(5)); assert_eq!(buffer.pop_first(), Some(6)); assert_eq!(buffer.pop_first(), None); } }