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