diff --git a/data/src/cycle_buffer.rs b/data/src/cycled_buffer.rs similarity index 68% rename from data/src/cycle_buffer.rs rename to data/src/cycled_buffer.rs index 0d63a1d..f4a3c2d 100644 --- a/data/src/cycle_buffer.rs +++ b/data/src/cycled_buffer.rs @@ -4,12 +4,12 @@ use std::ptr::NonNull; pub(crate) struct CycledBuffer { pos: BufferState, - data: Vec>, + data: Vec, } #[derive(Clone, Copy)] enum BufferState { - Filling(usize), - Cycle(usize), + Filling { unfilled_count: usize }, + Cycle { next_write_pos: usize }, Empty, } @@ -17,7 +17,9 @@ impl CycledBuffer { 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 CycledBuffer { 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 CycledBuffer { getter: G, ) -> impl Iterator { 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 { - 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 { @@ -75,6 +78,8 @@ impl CycledBuffer { } } + +/* impl Drop for CycledBuffer { fn drop(&mut self) { for e in self.data.iter_mut() { @@ -83,7 +88,7 @@ impl Drop for CycledBuffer { } } } -} +}*/ trait Len { fn len(&self) -> usize; @@ -119,15 +124,16 @@ impl E> CycledIterator { 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 E> Iterator for CycledIterator fn next(&mut self) -> Option { 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); } -} \ No newline at end of file +} diff --git a/data/src/lib.rs b/data/src/lib.rs index 925ddb4..c4422dd 100644 --- a/data/src/lib.rs +++ b/data/src/lib.rs @@ -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 { map: HashSet>)>