You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.6 KiB
Rust
136 lines
3.6 KiB
Rust
use crate::av::frame::Frame;
|
|
use std::collections::HashMap;
|
|
use std::fmt::{Debug, Error, Formatter};
|
|
use std::hash::Hash;
|
|
|
|
pub struct SortedBuffer<K: Copy, V> {
|
|
lowest_value: Option<K>,
|
|
sorted_keys: Vec<K>,
|
|
items: HashMap<K, V>,
|
|
open: bool,
|
|
buffer_size: usize,
|
|
}
|
|
|
|
impl<K: Debug + Copy + Eq + Hash, V: Debug> Debug for SortedBuffer<K, V> {
|
|
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<i64, Frame>;
|
|
|
|
impl SortedFrameBuffer {
|
|
pub fn insert_frame(&mut self, frame: Frame) -> bool {
|
|
self.insert(frame.pts(), frame)
|
|
}
|
|
}
|
|
|
|
impl<K: Copy + Debug + Eq + Hash, V: Debug> Default for SortedBuffer<K, V> {
|
|
fn default() -> Self {
|
|
SortedBuffer {
|
|
lowest_value: None,
|
|
sorted_keys: vec![],
|
|
items: Default::default(),
|
|
open: true,
|
|
buffer_size: 32,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<K: Copy + Debug + Eq + Hash + Ord, V: Debug> SortedBuffer<K, V> {
|
|
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<V> {
|
|
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);
|
|
}
|
|
}
|