diff --git a/README.md b/README.md index 816747b..2e6d58d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,14 @@ ## algorithm -将提供一些常用的数据结构以供使用。 +将提供一些常用的数据结构以供使用。目前提供的数据结构 +* **LruCache** 最近未使用缓存 +* **LruKCache** 最近未使用缓存, K次分类列表 +* **LfuCache** 按缓存访问次数做排序,优先淘汰访问最少次数的 +* **Slab** 仿linux中的Slab结构,对大对象做到初始化缓存使用 +* **BitMap** 位图, 按位做标记的图 +* **RoaringBitMap** 位图, 因为位图占用的内存太大, 对于稀疏位图会更小内存 +* **TimerWheel** 计时器轮, 模仿时钟的高效定时器组件 +* **CircularBuffer** 环形Buffer组件, 适用于内存限定较严格的, 设置不超过缓存值的环形结构 +* **RBTree** 红黑村, 高效的排序树, 可用于做定时器组件 # lru 全称是Least Recently Used,即最近最久未使用的意思。 每次元素访问将其更新到列表的最前,时间复杂度为O(1)。当达到容量限制时将淘汰双向列表中的链尾数据 diff --git a/examples/circular.rs b/examples/circular.rs index 9985373..e9ea74e 100644 --- a/examples/circular.rs +++ b/examples/circular.rs @@ -5,6 +5,6 @@ fn main() { circular.push_back(2); circular.push_back(3); assert_eq!(circular.len(), 2); - assert_eq!(circular[&0], 2); - assert_eq!(circular[&1], 3); + assert_eq!(circular[0], 2); + assert_eq!(circular[1], 3); } diff --git a/src/arr/circular_buffer.rs b/src/arr/circular_buffer.rs index dd9eb9c..9d02a97 100644 --- a/src/arr/circular_buffer.rs +++ b/src/arr/circular_buffer.rs @@ -1,4 +1,4 @@ -use std::ops::{Index, IndexMut}; +use std::{marker::PhantomData, ops::{Index, IndexMut}}; /// 循环的圆结构 /// 如果数据满了之后将自动在结尾后续添加,并保持最大个数 @@ -13,8 +13,8 @@ use std::ops::{Index, IndexMut}; /// circular.push_back(2); /// circular.push_back(3); /// assert_eq!(circular.len(), 2); -/// assert_eq!(circular[&0], 2); -/// assert_eq!(circular[&1], 3); +/// assert_eq!(circular[0], 2); +/// assert_eq!(circular[1], 3); /// } /// ``` pub struct CircularBuffer { @@ -139,7 +139,7 @@ impl CircularBuffer { /// assert_eq!(circular.is_empty(), true); /// circular.push_back(1); /// circular.push_back(2); - /// assert_eq!(circular[&0], 1); + /// assert_eq!(circular[0], 1); /// } /// ``` pub fn push_back(&mut self, val: T) { @@ -170,7 +170,7 @@ impl CircularBuffer { /// assert_eq!(circular.is_empty(), true); /// circular.push_front(1); /// circular.push_front(2); - /// assert_eq!(circular[&0], 2); + /// assert_eq!(circular[0], 2); /// } /// ``` pub fn push_front(&mut self, val: T) { @@ -202,9 +202,9 @@ impl CircularBuffer { /// assert_eq!(circular.is_empty(), true); /// circular.push_front(1); /// circular.push_front(2); - /// assert_eq!(circular[&0], 2); + /// assert_eq!(circular[0], 2); /// circular.pop_front(); - /// assert_eq!(circular[&0], 1); + /// assert_eq!(circular[0], 1); /// } /// ``` pub fn pop_front(&mut self) { @@ -224,9 +224,9 @@ impl CircularBuffer { /// assert_eq!(circular.is_empty(), true); /// circular.push_back(1); /// circular.push_back(2); - /// assert_eq!(circular[&0], 1); + /// assert_eq!(circular[0], 1); /// circular.pop_back(); - /// assert_eq!(circular[&0], 1); + /// assert_eq!(circular[0], 1); /// } /// ``` pub fn pop_back(&mut self) { @@ -261,16 +261,44 @@ impl CircularBuffer { cap: self.cap, } } + + /// 迭代更改器 + /// + /// # Examples + /// + /// ``` + /// use algorithm::CircularBuffer; + /// fn main() { + /// let mut circular = CircularBuffer::new(2); + /// assert_eq!(circular.is_empty(), true); + /// circular.push_back(1); + /// circular.push_back(2); + /// let val: Vec = circular.iter_mut().map(|v| { *v *= 2; *v }).collect(); + /// assert_eq!(val, vec![2, 4]); + /// let val: Vec = circular.iter_mut().rev().map(|v| { *v *= 2; *v }).collect(); + /// assert_eq!(val, vec![8, 4]); + /// } + /// ``` + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + IterMut { + arr: self.arr.as_mut_ptr(), + len: self.len, + head: self.head, + tail: self.tail, + cap: self.cap, + _marker: PhantomData, + } + } } -impl Index<&usize> for CircularBuffer { +impl Index for CircularBuffer { type Output = T; #[inline] - fn index(&self, index: &usize) -> &T { - if *index < self.len { - let ridx = (*index + self.head) % self.cap; + fn index(&self, index: usize) -> &T { + if index < self.len { + let ridx = (index + self.head) % self.cap; &self.arr[ridx] } else { panic!("index error"); @@ -278,11 +306,11 @@ impl Index<&usize> for CircularBuffer { } } -impl IndexMut<&usize> for CircularBuffer { +impl IndexMut for CircularBuffer { #[inline] - fn index_mut(&mut self, index: &usize) -> &mut T { - if *index < self.len { - let ridx = (*index + self.head) % self.cap; + fn index_mut(&mut self, index: usize) -> &mut T { + if index < self.len { + let ridx = (index + self.head) % self.cap; &mut self.arr[ridx] } else { panic!("index error"); @@ -341,8 +369,71 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } } +pub struct IterMut<'a, T: 'a> { + len: usize, + arr: *mut T, + head: usize, + tail: usize, + cap: usize, + _marker: PhantomData<&'a mut T>, +} +impl<'a, T> Iterator for IterMut<'a, T> { + type Item = &'a mut T; + fn next(&mut self) -> Option { + if self.len == 0 { + return None; + } + let now = self.head; + self.head = (self.head + 1) % self.cap; + self.len -= 1; + unsafe { + let ptr = self.arr.add(now); + return Some(&mut *ptr) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + + +impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { + fn next_back(&mut self) -> Option { + if self.len == 0 { + return None; + } + let now = self.tail; + self.tail = (self.tail + self.cap - 1) % self.cap; + self.len -= 1; + unsafe { + let ptr = self.arr.add(now); + return Some(&mut *ptr) + } + } +} + + + +impl PartialEq for CircularBuffer + where + T: Eq, +{ + fn eq(&self, other: &CircularBuffer) -> bool { + if self.len() != other.len() { + return false; + } + + self.iter().enumerate().all(|(idx, value)| &other[idx] == value) + } +} + +impl Eq for CircularBuffer + where + T: Eq, +{} #[cfg(test)] mod tests { @@ -350,6 +441,13 @@ mod tests { #[test] fn test_iter() { - + let mut circular = CircularBuffer::new(2); + assert_eq!(circular.is_empty(), true); + circular.push_back(1); + circular.push_back(2); + let val: Vec = circular.iter().map(|s| *s).collect(); + assert_eq!(val, vec![1, 2]); + let val: Vec = circular.iter().rev().map(|s| *s).collect(); + assert_eq!(val, vec![2, 1]); } } \ No newline at end of file