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