Checked push
This commit is contained in:
parent
1b794f076f
commit
60841ec34c
3 changed files with 38 additions and 10 deletions
|
@ -5,8 +5,7 @@ Yet another Rust ring buffer implementation.
|
||||||
**Early development**: more features will be added soon. Also, more tests. And probably breaking changes.
|
**Early development**: more features will be added soon. Also, more tests. And probably breaking changes.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
* Push element
|
* Checked/unchecked element/iterator safe push
|
||||||
* Push from iterator
|
|
||||||
* Mutable exact chunk iterator (read contiguous slices)
|
* Mutable exact chunk iterator (read contiguous slices)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
31
src/lib.rs
31
src/lib.rs
|
@ -21,13 +21,39 @@ impl<T> RingBuf<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, value: T) {
|
pub fn push(&mut self, value: T) -> bool {
|
||||||
|
if self.available < self.data.len() {
|
||||||
|
self.data[self.write_index] = value;
|
||||||
|
self.write_index = (self.write_index + 1) % self.data.len();
|
||||||
|
self.available = (self.available + 1).min(self.data.len());
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_unchecked(&mut self, value: T) {
|
||||||
self.data[self.write_index] = value;
|
self.data[self.write_index] = value;
|
||||||
self.write_index = (self.write_index + 1) % self.data.len();
|
self.write_index = (self.write_index + 1) % self.data.len();
|
||||||
self.available = (self.available + 1).min(self.data.len());
|
self.available = (self.available + 1).min(self.data.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_from_iter<I: Iterator<Item = T>>(&mut self, iter: I) {
|
pub fn push_from_iter<I: Iterator<Item = T>>(&mut self, mut iter: I) -> usize {
|
||||||
|
let mut len = 0;
|
||||||
|
while len < self.data.len() - self.available {
|
||||||
|
if let Some(value) = iter.next() {
|
||||||
|
self.data[self.write_index] = value;
|
||||||
|
self.write_index = (self.write_index + 1) % self.data.len();
|
||||||
|
len += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.available += len;
|
||||||
|
len
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_from_iter_unchecked<I: Iterator<Item = T>>(&mut self, iter: I) -> usize {
|
||||||
let mut len = 0;
|
let mut len = 0;
|
||||||
for value in iter {
|
for value in iter {
|
||||||
self.data[self.write_index] = value;
|
self.data[self.write_index] = value;
|
||||||
|
@ -35,6 +61,7 @@ impl<T> RingBuf<T> {
|
||||||
len += 1;
|
len += 1;
|
||||||
}
|
}
|
||||||
self.available = (self.available + len).min(self.data.len());
|
self.available = (self.available + len).min(self.data.len());
|
||||||
|
len
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> {
|
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> {
|
||||||
|
|
14
src/test.rs
14
src/test.rs
|
@ -9,11 +9,13 @@ fn correctness_random() {
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut ringbuf = RingBuf::new(1024, 0_u32);
|
let mut ringbuf = RingBuf::new(1024, 0_u32);
|
||||||
let mut buf = [0; 32];
|
|
||||||
let mut current_value = 0;
|
let mut current_value = 0;
|
||||||
for _ in 0_u32..1024 {
|
for _ in 0_u32..1024 {
|
||||||
let append_len = rng.gen_range(0..MAX_APPEND_LEN);
|
let append_len = rng.gen_range(0..MAX_APPEND_LEN);
|
||||||
ringbuf.push_from_iter(current_value as u32..current_value as u32 + append_len as u32);
|
assert_eq!(
|
||||||
|
ringbuf.push_from_iter(current_value as u32..current_value as u32 + append_len as u32),
|
||||||
|
append_len
|
||||||
|
);
|
||||||
for (j, chunk) in ringbuf.chunks_exact_mut(CHUNK_SIZE).enumerate() {
|
for (j, chunk) in ringbuf.chunks_exact_mut(CHUNK_SIZE).enumerate() {
|
||||||
assert_eq!(chunk.len(), CHUNK_SIZE);
|
assert_eq!(chunk.len(), CHUNK_SIZE);
|
||||||
for (k, v) in chunk.iter().enumerate() {
|
for (k, v) in chunk.iter().enumerate() {
|
||||||
|
@ -31,17 +33,17 @@ fn correctness_random() {
|
||||||
fn correctness_manual() {
|
fn correctness_manual() {
|
||||||
let mut ringbuf = RingBuf::new(8, 0_u32);
|
let mut ringbuf = RingBuf::new(8, 0_u32);
|
||||||
|
|
||||||
ringbuf.push_from_iter(1..4);
|
assert_eq!(ringbuf.push_from_iter(1..4), 3);
|
||||||
let mut iter = ringbuf.chunks_exact_mut(4);
|
let mut iter = ringbuf.chunks_exact_mut(4);
|
||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
ringbuf.push(4);
|
assert!(ringbuf.push(4));
|
||||||
let mut iter = ringbuf.chunks_exact_mut(4);
|
let mut iter = ringbuf.chunks_exact_mut(4);
|
||||||
assert_eq!(iter.next(), Some([1, 2, 3, 4].as_mut_slice()));
|
assert_eq!(iter.next(), Some([1, 2, 3, 4].as_mut_slice()));
|
||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
ringbuf.push_from_iter(5..8);
|
assert_eq!(ringbuf.push_from_iter(5..8), 3);
|
||||||
let mut iter = ringbuf.chunks_exact_mut(4);
|
let mut iter = ringbuf.chunks_exact_mut(4);
|
||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
ringbuf.push_from_iter(8..14);
|
assert_eq!(ringbuf.push_from_iter_unchecked(8..14), 6);
|
||||||
let mut iter = ringbuf.chunks_exact_mut(4);
|
let mut iter = ringbuf.chunks_exact_mut(4);
|
||||||
assert_eq!(iter.next(), Some([13, 6, 7, 8].as_mut_slice()));
|
assert_eq!(iter.next(), Some([13, 6, 7, 8].as_mut_slice()));
|
||||||
assert_eq!(iter.next(), Some([9, 10, 11, 12].as_mut_slice()));
|
assert_eq!(iter.next(), Some([9, 10, 11, 12].as_mut_slice()));
|
||||||
|
|
Loading…
Reference in a new issue