Skip to content

Commit 6ba638f

Browse files
committed
fix timer
1 parent faaa3eb commit 6ba638f

File tree

6 files changed

+461
-84
lines changed

6 files changed

+461
-84
lines changed

Diff for: Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ members = ["algorithm-macro"]
33

44
[package]
55
name = "algorithm"
6-
version = "0.1.12"
6+
version = "0.1.13"
77
edition = "2021"
88
authors = ["tickbh <[email protected]>"]
99
description = "about algorithm data structure, now has ttl with lru/lru-k/lfu/arc and slab/rbtree/roaring_bitmap/timer_wheelss, 关于算法常用的数据结构"

Diff for: src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub mod buf;
1313
pub use cache::{LruCache, LruKCache, LfuCache, ArcCache, Slab, Reinit};
1414
pub use tree::RBTree;
1515
pub use map::{BitMap, RoaringBitMap};
16-
pub use timer::{TimerWheel, Timer};
16+
pub use timer::{TimerWheel, Timer, TimerRBTree};
1717
pub use arr::{CircularBuffer, FixedVec};
1818
pub use util::*;
1919

Diff for: src/timer/mod.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,41 @@
11

2+
3+
pub trait Timer {
4+
/// 当时与现在的间隔,以确定插入确定的槽
5+
fn when(&self) -> u64;
6+
/// 可能需要修改对象,此处用可变值
7+
fn when_mut(&mut self) -> u64 {
8+
self.when()
9+
}
10+
}
11+
12+
macro_rules! impl_primitive_timer {
13+
($ty:ident) => {
14+
impl Timer for $ty {
15+
#[inline(always)]
16+
fn when(&self) -> u64 {
17+
*self as u64
18+
}
19+
}
20+
};
21+
}
22+
23+
impl_primitive_timer!(u8);
24+
impl_primitive_timer!(u16);
25+
impl_primitive_timer!(u32);
26+
impl_primitive_timer!(u64);
27+
impl_primitive_timer!(u128);
28+
impl_primitive_timer!(i8);
29+
impl_primitive_timer!(i16);
30+
impl_primitive_timer!(i32);
31+
impl_primitive_timer!(i64);
32+
impl_primitive_timer!(i128);
33+
impl_primitive_timer!(f32);
34+
impl_primitive_timer!(f64);
35+
impl_primitive_timer!(usize);
36+
37+
mod timer_rbtree;
238
mod timer_wheel;
339

4-
pub use timer_wheel::{TimerWheel, Timer};
40+
pub use timer_wheel::TimerWheel;
41+
pub use timer_rbtree::TimerRBTree;

Diff for: src/timer/timer_rbtree.rs

+312
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
use crate::HashMap;
2+
3+
use crate::RBTree;
4+
use std::cmp::Ordering;
5+
use std::vec;
6+
7+
use super::Timer;
8+
9+
#[derive(PartialEq, Eq)]
10+
struct TreeKey(u64, u64);
11+
12+
impl Ord for TreeKey {
13+
fn cmp(&self, other: &Self) -> Ordering {
14+
if self.0 != other.0 {
15+
return self.0.cmp(&other.0);
16+
}
17+
other.1.cmp(&self.1)
18+
}
19+
}
20+
21+
impl PartialOrd for TreeKey {
22+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
23+
Some(self.cmp(other))
24+
}
25+
}
26+
27+
/// 计时器轮,模拟时钟格式组成的高效计时器
28+
///
29+
/// 时间轮是一个环形的数据结构,可以想象成一个时钟的面,被分成多个格子
30+
///
31+
/// 每个格子代表一段时间,这段时间越短,定时器的精度就越高。
32+
///
33+
/// 每个格子用一个Vec存储放在该格子上的延时任务。
34+
///
35+
/// Mark: 在Rust中双向链表中暂未提供元素关键列表的接口,这里改用Vec,删除时会额外移动Vec值
36+
///
37+
/// # Examples
38+
///
39+
/// ```
40+
/// use algorithm::TimerRBTree;
41+
/// fn main() {
42+
/// let mut timer = TimerRBTree::new();
43+
/// timer.add_timer(30);
44+
/// assert_eq!(timer.tick_first(), Some(30));
45+
/// timer.add_timer(149);
46+
/// assert_eq!(timer.tick_first(), Some(30));
47+
/// let t = timer.add_timer(600);
48+
/// assert_eq!(timer.tick_first(), Some(30));
49+
/// timer.add_timer(1);
50+
/// assert_eq!(timer.tick_first(), Some(1));
51+
/// timer.del_timer(t);
52+
/// timer.add_timer(150);
53+
/// assert_eq!(timer.tick_first(), Some(1));
54+
/// let val = timer.update_deltatime(30).unwrap();
55+
/// assert_eq!(val, vec![1, 30]);
56+
/// timer.add_timer(2);
57+
/// let val = timer.update_deltatime(119).unwrap();
58+
/// assert_eq!(val, vec![2, 149]);
59+
/// let val = timer.update_deltatime(1).unwrap();
60+
/// assert_eq!(val, vec![150]);
61+
/// assert!(timer.is_empty());
62+
/// }
63+
/// ```
64+
pub struct TimerRBTree<T: Timer> {
65+
tree: RBTree<TreeKey, T>,
66+
67+
map: HashMap<u64, u64>,
68+
69+
/// 当时记录的时序
70+
cur_step: u64,
71+
72+
/// id记录
73+
next_timer_id: u64,
74+
}
75+
76+
impl<T: Timer> TimerRBTree<T> {
77+
pub fn new() -> Self {
78+
Self {
79+
tree: RBTree::new(),
80+
map: HashMap::new(),
81+
cur_step: 0,
82+
next_timer_id: 0,
83+
}
84+
}
85+
86+
/// 获取定时器的长度
87+
/// # Examples
88+
///
89+
/// ```
90+
/// use algorithm::TimerRBTree;
91+
/// fn main() {
92+
/// let mut timer = TimerRBTree::<u64>::new();
93+
/// assert!(timer.is_empty());
94+
/// timer.add_timer(1);
95+
/// assert_eq!(timer.len(), 1);
96+
/// let t = timer.add_timer(2);
97+
/// assert_eq!(timer.len(), 2);
98+
/// timer.del_timer(t);
99+
/// assert_eq!(timer.len(), 1);
100+
/// }
101+
/// ```
102+
pub fn len(&self) -> usize {
103+
self.tree.len()
104+
}
105+
106+
pub fn is_empty(&self) -> bool {
107+
self.tree.is_empty()
108+
}
109+
110+
/// 清除所有的槽位
111+
/// # Examples
112+
///
113+
/// ```
114+
/// use algorithm::TimerRBTree;
115+
/// fn main() {
116+
/// let mut timer = TimerRBTree::<u64>::new();
117+
/// assert!(timer.is_empty());
118+
/// timer.add_timer(1);
119+
/// timer.add_timer(2);
120+
/// assert_eq!(timer.len(), 2);
121+
/// timer.clear();
122+
/// assert_eq!(timer.len(), 0);
123+
/// }
124+
/// ```
125+
pub fn clear(&mut self) {
126+
self.tree.clear();
127+
self.map.clear();
128+
self.cur_step = 0;
129+
self.next_timer_id = 0;
130+
}
131+
132+
/// 添加定时器元素
133+
/// # Examples
134+
///
135+
/// ```
136+
/// use algorithm::TimerRBTree;
137+
/// fn main() {
138+
/// let mut timer = TimerRBTree::new();
139+
/// timer.add_timer(30);
140+
/// assert_eq!(timer.len(), 1);
141+
/// }
142+
pub fn add_timer(&mut self, val: T) -> u64 {
143+
let timer_id = self.next_timer_id;
144+
self.next_timer_id = self.next_timer_id.wrapping_add(1);
145+
let when = val.when();
146+
self.tree.insert(TreeKey(when, timer_id), val);
147+
self.map.insert(timer_id, when);
148+
timer_id
149+
}
150+
151+
/// 删除指定的定时器,时间复杂度为O(logn),
152+
///
153+
/// # Examples
154+
///
155+
/// ```
156+
/// use algorithm::TimerRBTree;
157+
/// fn main() {
158+
/// let mut timer = TimerRBTree::new();
159+
/// let t = timer.add_timer(30);
160+
/// timer.del_timer(t);
161+
/// assert_eq!(timer.len(), 0);
162+
/// }
163+
pub fn del_timer(&mut self, timer_id: u64) -> Option<T> {
164+
if let Some(when) = self.map.remove(&timer_id) {
165+
let tree = TreeKey(when, timer_id);
166+
self.tree.remove(&tree).map(|e| e)
167+
} else {
168+
None
169+
}
170+
}
171+
172+
/// 获取指定的定时器,时间复杂度为O(log(n))
173+
///
174+
/// # Examples
175+
///
176+
/// ```
177+
/// use algorithm::TimerRBTree;
178+
/// fn main() {
179+
/// let mut timer = TimerRBTree::new();
180+
/// let t = timer.add_timer(30);
181+
/// assert_eq!(timer.get_timer(&t), Some(&30));
182+
/// }
183+
pub fn get_timer(&self, timer_id: &u64) -> Option<&T> {
184+
if let Some(when) = self.map.get(timer_id) {
185+
let tree = TreeKey(*when, *timer_id);
186+
self.tree.get(&tree).map(|e| e)
187+
} else {
188+
None
189+
}
190+
}
191+
192+
/// 获取指定的定时器,时间复杂度为O(log(n))
193+
///
194+
/// # Examples
195+
///
196+
/// ```
197+
/// use algorithm::TimerRBTree;
198+
/// fn main() {
199+
/// let mut timer = TimerRBTree::new();
200+
/// let t = timer.add_timer(30);
201+
/// *timer.get_mut_timer(&t).unwrap() = 33;
202+
/// let val = timer.update_deltatime(30).unwrap();
203+
/// assert_eq!(val, vec![33]);
204+
/// }
205+
pub fn get_mut_timer(&mut self, timer_id: &u64) -> Option<&mut T> {
206+
if let Some(when) = self.map.get(timer_id) {
207+
let tree = TreeKey(*when, *timer_id);
208+
self.tree.get_mut(&tree).map(|e| e)
209+
} else {
210+
None
211+
}
212+
}
213+
214+
/// 取出时间轴最小的一个值
215+
pub fn tick_first(&self) -> Option<u64> {
216+
self.tree
217+
.get_first()
218+
.map(|(key, _)| Some(key.0))
219+
.unwrap_or(None)
220+
}
221+
222+
/// 判断到指定时间是否有小于该指定值的实例
223+
pub fn tick_time(&mut self, tm: u64) -> Option<T> {
224+
if tm < self.tick_first().unwrap_or(tm + 1) {
225+
return None;
226+
}
227+
self.tree.pop_first().map(|(_, e)| e)
228+
}
229+
230+
/// 计时器轮的递进时间
231+
///
232+
/// # Examples
233+
///
234+
/// ```
235+
/// use algorithm::TimerRBTree;
236+
/// fn main() {
237+
/// let mut timer = TimerRBTree::new();
238+
/// timer.add_timer(30);
239+
/// let val = timer.update_deltatime(30).unwrap();
240+
/// assert_eq!(val, vec![30]);
241+
/// }
242+
pub fn update_now(&mut self, now: u64) -> Option<Vec<T>> {
243+
self.cur_step = now;
244+
let mut result = vec![];
245+
loop {
246+
if let Some(val) = self.tick_first() {
247+
if self.cur_step < val {
248+
break;
249+
}
250+
result.push(self.tree.pop_first().map(|(_, e)| e).unwrap());
251+
} else {
252+
break;
253+
}
254+
}
255+
Some(result)
256+
}
257+
/// 计时器轮的递进时间
258+
///
259+
/// # Examples
260+
///
261+
/// ```
262+
/// use algorithm::TimerRBTree;
263+
/// fn main() {
264+
/// let mut timer = TimerRBTree::new();
265+
/// timer.add_timer(30);
266+
/// let val = timer.update_deltatime(30).unwrap();
267+
/// assert_eq!(val, vec![30]);
268+
/// }
269+
pub fn update_deltatime(&mut self, delta: u64) -> Option<Vec<T>> {
270+
self.update_now(self.cur_step.wrapping_add(delta))
271+
}
272+
273+
/// 计时器轮的递进时间
274+
///
275+
/// # Examples
276+
///
277+
/// ```
278+
/// use algorithm::TimerRBTree;
279+
/// fn main() {
280+
/// let mut timer = TimerRBTree::new();
281+
/// timer.add_timer(30);
282+
/// let mut idx = 0;
283+
/// timer.update_deltatime_with_callback(30, &mut |_, v| {
284+
/// idx = v;
285+
/// None
286+
/// });
287+
/// assert_eq!(idx, 30);
288+
/// }
289+
pub fn update_deltatime_with_callback<F>(&mut self, delta: u64, f: &mut F)
290+
where
291+
F: FnMut(&mut Self, T) -> Option<T>,
292+
{
293+
self.update_now_with_callback(self.cur_step.wrapping_add(delta), f)
294+
}
295+
296+
pub fn update_now_with_callback<F>(&mut self, now: u64, f: &mut F)
297+
where
298+
F: FnMut(&mut Self, T) -> Option<T>,
299+
{
300+
if let Some(result) = self.update_now(now) {
301+
let mut collect_result = vec![];
302+
for r in result.into_iter() {
303+
if let Some(v) = (*f)(self, r) {
304+
collect_result.push(v);
305+
}
306+
}
307+
for v in collect_result.drain(..) {
308+
self.add_timer(v);
309+
}
310+
}
311+
}
312+
}

0 commit comments

Comments
 (0)