ringbuffer.rs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 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. use std::collections::{vec_deque::Iter, VecDeque};
  19. /// A ring buffer of fixed capacity
  20. #[derive(Default, Eq, PartialEq, Clone, Debug)]
  21. pub struct RingBuffer<T, const N: usize>(VecDeque<T>);
  22. impl<T: Eq + PartialEq + Clone, const N: usize> RingBuffer<T, N> {
  23. /// Create a new [`RingBuffer`] with given fixed capacity
  24. pub fn new() -> RingBuffer<T, N> {
  25. Self(VecDeque::with_capacity(N))
  26. }
  27. /// Push an element to the back of the `RingBuffer`, removing
  28. /// the front element in case the buffer is full.
  29. pub fn push(&mut self, value: T) {
  30. if self.0.len() == N {
  31. self.0.pop_front();
  32. }
  33. self.0.push_back(value);
  34. }
  35. /// Returns the current number of items in the buffer
  36. pub fn len(&self) -> usize {
  37. self.0.len()
  38. }
  39. /// Returns true if buffer is empty, false otherwise
  40. pub fn is_empty(&self) -> bool {
  41. self.0.is_empty()
  42. }
  43. /// Removes and returns the oldest item in the buffer
  44. pub fn pop(&mut self) -> Option<T> {
  45. self.0.pop_front()
  46. }
  47. /// Returns a front-to-back iterator
  48. pub fn iter(&self) -> Iter<'_, T> {
  49. self.0.iter()
  50. }
  51. /// Returns true if the buffer contains an element equal to the given value
  52. pub fn contains(&self, x: &T) -> bool {
  53. self.0.contains(x)
  54. }
  55. /// Provides a reference to the back element, or `None` if empty.
  56. pub fn back(&self) -> Option<&T> {
  57. self.0.back()
  58. }
  59. }
  60. #[cfg(test)]
  61. mod tests {
  62. use super::*;
  63. #[test]
  64. fn behaviour() {
  65. const BUF_SIZE: usize = 10;
  66. let mut buf = RingBuffer::<BUF_SIZE>::new();
  67. for i in 0..BUF_SIZE {
  68. buf.push(i);
  69. }
  70. assert!(!buf.is_empty());
  71. assert!(buf.len() == BUF_SIZE);
  72. for i in 0..BUF_SIZE {
  73. buf.push(i + 10);
  74. }
  75. assert!(buf.len() == BUF_SIZE);
  76. for (i, v) in buf.iter().enumerate() {
  77. assert_eq!(*v, i + 10);
  78. }
  79. }
  80. }