Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/cli/src/util/ring_buffer.rs
3314 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
pub struct RingBuffer<T> {
7
data: Vec<T>,
8
i: usize,
9
}
10
11
impl<T> RingBuffer<T> {
12
pub fn new(capacity: usize) -> Self {
13
Self {
14
data: Vec::with_capacity(capacity),
15
i: 0,
16
}
17
}
18
19
pub fn capacity(&self) -> usize {
20
self.data.capacity()
21
}
22
23
pub fn len(&self) -> usize {
24
self.data.len()
25
}
26
27
pub fn is_full(&self) -> bool {
28
self.data.len() == self.data.capacity()
29
}
30
31
pub fn is_empty(&self) -> bool {
32
self.data.len() == 0
33
}
34
35
pub fn push(&mut self, value: T) {
36
if self.data.len() == self.data.capacity() {
37
self.data[self.i] = value;
38
} else {
39
self.data.push(value);
40
}
41
42
self.i = (self.i + 1) % self.data.capacity();
43
}
44
45
pub fn iter(&self) -> RingBufferIter<'_, T> {
46
RingBufferIter {
47
index: 0,
48
buffer: self,
49
}
50
}
51
}
52
53
impl<T: Default> IntoIterator for RingBuffer<T> {
54
type Item = T;
55
type IntoIter = OwnedRingBufferIter<T>;
56
57
fn into_iter(self) -> OwnedRingBufferIter<T>
58
where
59
T: Default,
60
{
61
OwnedRingBufferIter {
62
index: 0,
63
buffer: self,
64
}
65
}
66
}
67
68
pub struct OwnedRingBufferIter<T: Default> {
69
buffer: RingBuffer<T>,
70
index: usize,
71
}
72
73
impl<T: Default> Iterator for OwnedRingBufferIter<T> {
74
type Item = T;
75
76
fn next(&mut self) -> Option<Self::Item> {
77
if self.index == self.buffer.len() {
78
return None;
79
}
80
81
let ii = (self.index + self.buffer.i) % self.buffer.len();
82
let item = std::mem::take(&mut self.buffer.data[ii]);
83
self.index += 1;
84
Some(item)
85
}
86
}
87
88
pub struct RingBufferIter<'a, T> {
89
buffer: &'a RingBuffer<T>,
90
index: usize,
91
}
92
93
impl<'a, T> Iterator for RingBufferIter<'a, T> {
94
type Item = &'a T;
95
96
fn next(&mut self) -> Option<Self::Item> {
97
if self.index == self.buffer.len() {
98
return None;
99
}
100
101
let ii = (self.index + self.buffer.i) % self.buffer.len();
102
let item = &self.buffer.data[ii];
103
self.index += 1;
104
Some(item)
105
}
106
}
107
108
#[cfg(test)]
109
mod tests {
110
use super::*;
111
112
#[test]
113
fn test_inserts() {
114
let mut rb = RingBuffer::new(3);
115
assert_eq!(rb.capacity(), 3);
116
assert!(!rb.is_full());
117
assert_eq!(rb.len(), 0);
118
assert_eq!(rb.iter().copied().count(), 0);
119
120
rb.push(1);
121
assert!(!rb.is_full());
122
assert_eq!(rb.len(), 1);
123
assert_eq!(rb.iter().copied().collect::<Vec<i32>>(), vec![1]);
124
125
rb.push(2);
126
assert!(!rb.is_full());
127
assert_eq!(rb.len(), 2);
128
assert_eq!(rb.iter().copied().collect::<Vec<i32>>(), vec![1, 2]);
129
130
rb.push(3);
131
assert!(rb.is_full());
132
assert_eq!(rb.len(), 3);
133
assert_eq!(rb.iter().copied().collect::<Vec<i32>>(), vec![1, 2, 3]);
134
135
rb.push(4);
136
assert!(rb.is_full());
137
assert_eq!(rb.len(), 3);
138
assert_eq!(rb.iter().copied().collect::<Vec<i32>>(), vec![2, 3, 4]);
139
140
assert_eq!(rb.into_iter().collect::<Vec<i32>>(), vec![2, 3, 4]);
141
}
142
}
143
144