ringbuf.rs
1 /* This file is part of DarkFi (https://dark.fi) 2 * 3 * Copyright (C) 2020-2025 Dyne.org foundation 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Affero General Public License as 7 * published by the Free Software Foundation, either version 3 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Affero General Public License for more details. 14 * 15 * You should have received a copy of the GNU Affero General Public License 16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 */ 18 19 #[derive(Clone)] 20 pub struct RingBuffer<T, const N: usize> { 21 vals: [Option<T>; N], 22 head: i64, 23 tail: i64, 24 } 25 26 impl<T, const N: usize> RingBuffer<T, N> { 27 const LEN: usize = N; 28 29 pub fn new() -> Self { 30 Self { vals: [const { None }; N], head: -1, tail: -1 } 31 } 32 33 pub fn push(&mut self, v: T) { 34 let len = Self::LEN as i64; 35 36 self.head = (self.head + 1) % len; 37 if self.head == self.tail { 38 self.tail = (self.tail + 1) % len; 39 } 40 41 if self.tail < 0 { 42 self.tail = 0; 43 } 44 45 let _ = std::mem::replace(&mut self.vals[self.head as usize], Some(v)); 46 } 47 48 pub fn head(&self) -> Option<&T> { 49 if self.head < 0 { 50 return None 51 } 52 Some(self.vals[self.head as usize].as_ref().unwrap()) 53 } 54 55 pub fn tail(&self) -> Option<&T> { 56 if self.tail < 0 { 57 return None 58 } 59 Some(self.vals[self.tail as usize].as_ref().unwrap()) 60 } 61 }