znippy_common/
int_ring.rs1pub const MINI_SIZE: usize = 4; pub const MEDIUM_SIZE: usize = 32; pub const LARGE_SIZE: usize = 128; pub const STORLEK_ENORM: usize = 8192; struct RingState {
18 head: usize,
19 tail: usize,
20 len: usize,
21}
22
23struct RingInner<const N: usize> {
24 buf: Box<[u64; N]>,
25 state: RingState,
26}
27
28impl<const N: usize> RingInner<N> {
29 fn new() -> Self {
30 let array = Box::new([0u64; N]);
31 Self {
32 buf: array,
33 state: RingState {
34 head: 0,
35 tail: 0,
36 len: 0, },
38 }
39 }
40
41 fn pop(&mut self) -> Option<u64> {
42 if self.state.len == 0 {
43 None
44 } else {
45 let val = self.buf[self.state.tail];
46 self.state.tail = (self.state.tail + 1) % N;
47 self.state.len -= 1;
48 Some(val)
49 }
50 }
51
52 fn push(&mut self, val: u64) -> Result<(), &'static str> {
53 if self.is_full() {
54 return Err("RingBuffer overflow: push attempted while full");
55 }
56 self.buf[self.state.head] = val;
57 self.state.head = (self.state.head + 1) % N;
58 self.state.len += 1;
59 Ok(())
60 }
61 fn is_empty(&self) -> bool {
62 self.state.len == 0
63 }
64
65 fn is_full(&self) -> bool {
66 self.state.len == N
67 }
68
69 fn capacity(&self) -> usize {
70 N
71 }
72}
73
74pub enum RingBuffer {
75 Mini(RingInner<MINI_SIZE>),
76 Medium(RingInner<MEDIUM_SIZE>),
77 Large(RingInner<LARGE_SIZE>),
78 StorlekEnorm(RingInner<STORLEK_ENORM>),
79}
80
81pub trait ChunkQueue {
82 fn pop(&mut self) -> Option<u64>;
83 fn push(&mut self, val: u64) -> Result<(), &'static str>;
84 fn is_empty(&self) -> bool;
85 fn is_full(&self) -> bool;
86 fn capacity(&self) -> usize;
87}
88
89impl RingBuffer {
90 pub fn new(max_chunks: usize) -> Self {
91 if max_chunks <= MINI_SIZE {
92 RingBuffer::Mini(RingInner::new())
93 } else if max_chunks <= MEDIUM_SIZE {
94 RingBuffer::Medium(RingInner::new())
95 } else if max_chunks <= LARGE_SIZE {
96 RingBuffer::Large(RingInner::new())
97 } else {
98 RingBuffer::StorlekEnorm(RingInner::new())
99 }
100 }
101}
102
103impl ChunkQueue for RingBuffer {
104 fn pop(&mut self) -> Option<u64> {
105 match self {
106 RingBuffer::Mini(inner) => inner.pop(),
107 RingBuffer::Medium(inner) => inner.pop(),
108 RingBuffer::Large(inner) => inner.pop(),
109 RingBuffer::StorlekEnorm(inner) => inner.pop(),
110 }
111 }
112
113 fn push(&mut self, val: u64) -> Result<(), &'static str> {
114 match self {
115 RingBuffer::Mini(inner) => inner.push(val),
116 RingBuffer::Medium(inner) => inner.push(val),
117 RingBuffer::Large(inner) => inner.push(val),
118 RingBuffer::StorlekEnorm(inner) => inner.push(val),
119 }
120 }
121
122 fn is_empty(&self) -> bool {
123 match self {
124 RingBuffer::Mini(inner) => inner.is_empty(),
125 RingBuffer::Medium(inner) => inner.is_empty(),
126 RingBuffer::Large(inner) => inner.is_empty(),
127 RingBuffer::StorlekEnorm(inner) => inner.is_empty(),
128 }
129 }
130
131 fn is_full(&self) -> bool {
132 match self {
133 RingBuffer::Mini(inner) => inner.is_full(),
134 RingBuffer::Medium(inner) => inner.is_full(),
135 RingBuffer::Large(inner) => inner.is_full(),
136 RingBuffer::StorlekEnorm(inner) => inner.is_full(),
137 }
138 }
139
140 fn capacity(&self) -> usize {
141 match self {
142 RingBuffer::Mini(inner) => inner.capacity(),
143 RingBuffer::Medium(inner) => inner.capacity(),
144 RingBuffer::Large(inner) => inner.capacity(),
145 RingBuffer::StorlekEnorm(inner) => inner.capacity(),
146 }
147 }
148}