Skip to main content

buffer_core/
lib.rs

1pub mod buffer;
2pub mod lease;
3pub mod reclaim;
4pub mod shared;
5pub mod shm;
6
7use std::collections::HashMap;
8
9use core_types::BufferId;
10
11pub use buffer::{Buffer, BufferKind};
12pub use lease::{BufferLease, PacketView};
13pub use reclaim::{NoopReclaimer, ReclaimPolicy};
14pub use shared::SharedBufferDescriptor;
15pub use shm::{
16    SharedMemoryBufferRef, SharedMemoryReader, SharedMemoryWriter, ShmRateLimitConfig,
17    ShmTransportConfig,
18};
19
20pub trait BufferLeaseProvider {
21    fn allocate(&mut self, data: Vec<u8>) -> BufferLease;
22    fn get(&self, id: BufferId) -> Option<BufferLease>;
23    fn release(&mut self, id: BufferId);
24}
25
26#[derive(Default)]
27pub struct SimpleBufferPool {
28    next_id: u64,
29    buffers: HashMap<BufferId, Buffer>,
30    active_leases: usize,
31}
32
33impl SimpleBufferPool {
34    pub fn new() -> Self {
35        Self::default()
36    }
37
38    /// Returns the number of buffers currently allocated and not yet released.
39    pub fn outstanding_leases(&self) -> usize {
40        self.active_leases
41    }
42
43    /// Panics (in debug builds and tests) if there are any unreleased buffers.
44    /// Use at the end of a test to confirm there are no buffer leaks.
45    #[cfg(any(debug_assertions, test))]
46    pub fn assert_no_leaks(&self) {
47        assert_eq!(
48            self.active_leases, 0,
49            "buffer leak detected: {} outstanding lease(s)",
50            self.active_leases
51        );
52    }
53}
54
55impl BufferLeaseProvider for SimpleBufferPool {
56    fn allocate(&mut self, data: Vec<u8>) -> BufferLease {
57        self.next_id += 1;
58        let buffer = Buffer::from_vec(BufferId::new(self.next_id), data);
59        let lease = BufferLease::full(buffer.clone());
60        self.buffers.insert(buffer.id, buffer);
61        self.active_leases += 1;
62        lease
63    }
64
65    fn get(&self, id: BufferId) -> Option<BufferLease> {
66        self.buffers.get(&id).cloned().map(BufferLease::full)
67    }
68
69    fn release(&mut self, id: BufferId) {
70        if self.buffers.remove(&id).is_some() {
71            self.active_leases = self.active_leases.saturating_sub(1);
72        }
73    }
74}