blob: 59b5323c7c23077be1271752f47409e76087d493 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::collections::VecDeque;
/// A Memory bounded buffer. MemoryBoundedBuffer does not calculate the size of `item`,
/// rather it takes the size as argument and then maintains its internal buffer.
/// Oldest item(s) are deleted in the event of buffer overflow.
pub(super) struct MemoryBoundedBuffer<T> {
inner: VecDeque<(T, usize)>,
total_size: usize,
capacity: usize,
}
impl<T> MemoryBoundedBuffer<T> {
pub fn new(capacity: usize) -> MemoryBoundedBuffer<T> {
assert!(capacity > 0, "capacity should be more than 0");
MemoryBoundedBuffer { inner: VecDeque::new(), capacity: capacity, total_size: 0 }
}
pub fn push(&mut self, item: T, size: usize) {
self.inner.push_back((item, size));
self.total_size += size;
while self.total_size > self.capacity {
let removed_size = self.inner.pop_front().expect("there are items if reducing size").1;
self.total_size -= removed_size;
}
}
pub fn iter(&mut self) -> impl Iterator<Item = &(T, usize)> {
self.inner.iter()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple() {
let mut m = MemoryBoundedBuffer::new(12);
m.push(1, 4);
m.push(2, 4);
m.push(3, 4);
assert_eq!(&m.iter().collect::<Vec<&(i32, usize)>>()[..], &[&(1, 4), &(2, 4), &(3, 4)]);
}
#[test]
fn test_bound() {
let mut m = MemoryBoundedBuffer::new(12);
m.push(1, 4);
m.push(2, 4);
m.push(3, 5);
assert_eq!(&m.iter().collect::<Vec<&(i32, usize)>>()[..], &[&(2, 4), &(3, 5)]);
m.push(4, 4);
m.push(5, 4);
assert_eq!(&m.iter().collect::<Vec<&(i32, usize)>>()[..], &[&(4, 4), &(5, 4)]);
}
}