Reversed iterator in cycled buffer
This commit is contained in:
parent
a61c5332a0
commit
ff64f16bde
@ -4,12 +4,12 @@ use std::ptr::NonNull;
|
||||
|
||||
pub(crate) struct CycledBuffer<T> {
|
||||
pos: BufferState,
|
||||
data: Vec<ManuallyDrop<T>>,
|
||||
data: Vec<T>,
|
||||
}
|
||||
#[derive(Clone, Copy)]
|
||||
enum BufferState {
|
||||
Filling(usize),
|
||||
Cycle(usize),
|
||||
Filling { unfilled_count: usize },
|
||||
Cycle { next_write_pos: usize },
|
||||
Empty,
|
||||
}
|
||||
|
||||
@ -17,7 +17,9 @@ impl<T> CycledBuffer<T> {
|
||||
pub fn new(capacity: usize) -> Self {
|
||||
return Self {
|
||||
pos: if capacity > 0 {
|
||||
BufferState::Filling(capacity)
|
||||
BufferState::Filling {
|
||||
unfilled_count: capacity,
|
||||
}
|
||||
} else {
|
||||
BufferState::Empty
|
||||
},
|
||||
@ -27,23 +29,22 @@ impl<T> CycledBuffer<T> {
|
||||
|
||||
pub fn push(&mut self, value: T) {
|
||||
match self.pos {
|
||||
BufferState::Filling(mut left) => {
|
||||
self.data.push(ManuallyDrop::new(value));
|
||||
left -= 1;
|
||||
if left == 0 {
|
||||
self.pos = BufferState::Cycle(0);
|
||||
BufferState::Filling { mut unfilled_count } => {
|
||||
self.data.push(value);
|
||||
unfilled_count -= 1;
|
||||
if unfilled_count == 0 {
|
||||
self.pos = BufferState::Cycle { next_write_pos: 0 };
|
||||
} else {
|
||||
self.pos = BufferState::Filling(left);
|
||||
self.pos = BufferState::Filling { unfilled_count };
|
||||
}
|
||||
}
|
||||
BufferState::Cycle(mut pos) => {
|
||||
unsafe { ManuallyDrop::drop(&mut self.data[pos]) };
|
||||
self.data[pos] = ManuallyDrop::new(value);
|
||||
pos += 1;
|
||||
if pos >= self.data.len() {
|
||||
self.pos = BufferState::Cycle(0);
|
||||
BufferState::Cycle { mut next_write_pos } => {
|
||||
self.data[next_write_pos] = value;
|
||||
next_write_pos += 1;
|
||||
if next_write_pos >= self.data.len() {
|
||||
self.pos = BufferState::Cycle { next_write_pos: 0 };
|
||||
} else {
|
||||
self.pos = BufferState::Cycle(pos);
|
||||
self.pos = BufferState::Cycle { next_write_pos };
|
||||
}
|
||||
}
|
||||
BufferState::Empty => {
|
||||
@ -58,14 +59,16 @@ impl<T> CycledBuffer<T> {
|
||||
getter: G,
|
||||
) -> impl Iterator<Item = E> {
|
||||
match state {
|
||||
BufferState::Filling(_) => return CycledIterator::start(collection, 0, getter),
|
||||
BufferState::Cycle(middle) => return CycledIterator::start(collection, middle, getter),
|
||||
BufferState::Filling { .. } => return CycledIterator::start(collection, 0, getter),
|
||||
BufferState::Cycle { next_write_pos } => {
|
||||
return CycledIterator::start(collection, next_write_pos, getter);
|
||||
}
|
||||
BufferState::Empty => return CycledIterator::ended(collection, getter),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
||||
return Self::_iter(self.pos, &self.data, |c, i| c[i].deref());
|
||||
return Self::_iter(self.pos, &self.data, |c, i| &c[i]);
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
||||
@ -75,6 +78,8 @@ impl<T> CycledBuffer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
impl<T> Drop for CycledBuffer<T> {
|
||||
fn drop(&mut self) {
|
||||
for e in self.data.iter_mut() {
|
||||
@ -83,7 +88,7 @@ impl<T> Drop for CycledBuffer<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
trait Len {
|
||||
fn len(&self) -> usize;
|
||||
@ -119,15 +124,16 @@ impl<C: Len, E, G: Fn(&mut C, usize) -> E> CycledIterator<C, E, G> {
|
||||
if middle > 0 {
|
||||
return Self {
|
||||
collection,
|
||||
state: IteratorState::End { middle },
|
||||
pos: middle,
|
||||
state: IteratorState::Start { middle },
|
||||
pos: middle - 1,
|
||||
getter,
|
||||
};
|
||||
} else {
|
||||
let pos = collection.len() - 1;
|
||||
return Self {
|
||||
collection,
|
||||
state: IteratorState::Plain,
|
||||
pos: 0,
|
||||
pos,
|
||||
getter,
|
||||
};
|
||||
};
|
||||
@ -148,39 +154,40 @@ impl<C: Len, E, G: Fn(&mut C, usize) -> E> Iterator for CycledIterator<C, E, G>
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.state {
|
||||
IteratorState::End { middle } => {
|
||||
let e = (self.getter)(&mut self.collection, self.pos);
|
||||
self.pos += 1;
|
||||
if self.pos >= self.collection.len() {
|
||||
self.state = IteratorState::Start { middle };
|
||||
self.pos = 0;
|
||||
}
|
||||
return Some(e);
|
||||
}
|
||||
IteratorState::Start { middle } => {
|
||||
let e = (self.getter)(&mut self.collection, self.pos);
|
||||
self.pos += 1;
|
||||
if self.pos >= middle {
|
||||
match self.pos.checked_sub(1) {
|
||||
Some(pos) => self.pos = pos,
|
||||
None => {
|
||||
self.pos = self.collection.len() - 1;
|
||||
self.state = IteratorState::End { middle };
|
||||
}
|
||||
}
|
||||
|
||||
return Some(e);
|
||||
}
|
||||
IteratorState::End { middle } => {
|
||||
let e = (self.getter)(&mut self.collection, self.pos);
|
||||
if self.pos == middle {
|
||||
self.state = IteratorState::Done;
|
||||
}
|
||||
self.pos -= 1;
|
||||
return Some(e);
|
||||
}
|
||||
IteratorState::Done => return None,
|
||||
IteratorState::Plain => {
|
||||
if self.pos < self.collection.len() {
|
||||
let e = (self.getter)(&mut self.collection, self.pos);
|
||||
self.pos += 1;
|
||||
return Some(e);
|
||||
let e = (self.getter)(&mut self.collection, self.pos);
|
||||
if self.pos > 0 {
|
||||
self.pos -= 1;
|
||||
} else {
|
||||
self.state = IteratorState::Done;
|
||||
return None;
|
||||
}
|
||||
return Some(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod _tests {
|
||||
use super::CycledBuffer;
|
||||
@ -192,8 +199,8 @@ mod _tests {
|
||||
b.push(9);
|
||||
|
||||
let mut it = b.iter();
|
||||
assert_eq!(it.next(), Some(&6));
|
||||
assert_eq!(it.next(), Some(&9));
|
||||
assert_eq!(it.next(), Some(&6));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
#[test]
|
||||
@ -204,8 +211,8 @@ mod _tests {
|
||||
b.push(2);
|
||||
|
||||
let mut it = b.iter();
|
||||
assert_eq!(it.next(), Some(&5));
|
||||
assert_eq!(it.next(), Some(&2));
|
||||
assert_eq!(it.next(), Some(&5));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
mod cycle_buffer;
|
||||
mod cycled_buffer;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use bgtu_networks_2_gui_abstract::ServersStorage as ServersGuiCtx;
|
||||
use bgtu_networks_2_network_abstract::{Address, ServersContext as ServersNetworkCtx};
|
||||
use crate::cycle_buffer::CycledBuffer;
|
||||
use crate::cycled_buffer::CycledBuffer;
|
||||
|
||||
struct ServersStorage<A: Address> {
|
||||
map: HashSet<A, (String, CycledBuffer<Option<u32>>)>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user