Skip to content

Commit

Permalink
timer
Browse files Browse the repository at this point in the history
  • Loading branch information
tickbh committed Nov 20, 2024
1 parent 90d3c19 commit 273ba6b
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 57 deletions.
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub mod buf;
pub use cache::{LruCache, LruKCache, LfuCache, ArcCache, Slab, Reinit};
pub use tree::RBTree;
pub use map::{BitMap, RoaringBitMap};
pub use timer::{TimerWheel, Timer, TimerRBTree};
pub use timer::{TimerWheel, Timer, TimerRBTree, StampTimer};
pub use arr::{CircularBuffer, FixedVec};
pub use util::*;

Expand Down
2 changes: 2 additions & 0 deletions src/timer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ impl_primitive_timer!(usize);

mod timer_rbtree;
mod timer_wheel;
mod stamp_timer;

pub use timer_wheel::TimerWheel;
pub use timer_rbtree::TimerRBTree;
pub use stamp_timer::StampTimer;
43 changes: 43 additions & 0 deletions src/timer/stamp_timer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use super::Timer;

pub struct StampTimer<T> {
duration: Duration,
is_sec: bool,
pub val: T,
}

impl<T> StampTimer<T> {
pub fn new(val: T, duration: Duration) -> Self {
let is_sec = duration.as_secs() as u128 * 1000 == duration.as_millis();
Self { val, duration, is_sec }
}

pub fn new_second(val: T, interval: u64) -> Self {
Self {
val,
duration: Duration::from_secs(interval),
is_sec: true,
}
}

pub fn new_millis(val: T, interval: u64) -> Self {
Self {
val,
duration: Duration::from_millis(interval),
is_sec: false,
}
}
}

impl<T> Timer for StampTimer<T> {
fn when(&self) -> u64 {
let when = SystemTime::now() + self.duration;
if self.is_sec {
when.duration_since(UNIX_EPOCH).unwrap().as_secs()
} else {
when.duration_since(UNIX_EPOCH).unwrap().as_millis() as u64
}
}
}
76 changes: 55 additions & 21 deletions src/timer/timer_rbtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::HashMap;

use crate::RBTree;
use std::cmp::Ordering;
use std::u64;
use std::vec;

use super::Timer;
Expand Down Expand Up @@ -52,12 +53,12 @@ impl PartialOrd for TreeKey {
/// timer.add_timer(150);
/// assert_eq!(timer.tick_first(), Some(1));
/// let val = timer.update_deltatime(30).unwrap();
/// assert_eq!(val, vec![1, 30]);
/// assert_eq!(val.iter().map(|(_, v)| *v).collect::<Vec<usize>>(), vec![1, 30]);
/// timer.add_timer(2);
/// let val = timer.update_deltatime(119).unwrap();
/// assert_eq!(val, vec![2, 149]);
/// assert_eq!(val.iter().map(|(_, v)| *v).collect::<Vec<usize>>(), vec![2, 149]);
/// let val = timer.update_deltatime(1).unwrap();
/// assert_eq!(val, vec![150]);
/// assert_eq!(val.iter().map(|(_, v)| *v).collect::<Vec<usize>>(), vec![150]);
/// assert!(timer.is_empty());
/// }
/// ```
Expand All @@ -71,6 +72,8 @@ pub struct TimerRBTree<T: Timer> {

/// id记录
next_timer_id: u64,
/// max id
max_timer_id: u64,
}

impl<T: Timer> TimerRBTree<T> {
Expand All @@ -79,7 +82,8 @@ impl<T: Timer> TimerRBTree<T> {
tree: RBTree::new(),
map: HashMap::new(),
cur_step: 0,
next_timer_id: 0,
next_timer_id: 1,
max_timer_id: u64::MAX,
}
}

Expand Down Expand Up @@ -126,7 +130,32 @@ impl<T: Timer> TimerRBTree<T> {
self.tree.clear();
self.map.clear();
self.cur_step = 0;
self.next_timer_id = 0;
self.next_timer_id = 1;
}

pub fn get_max_timerid(&self) -> u64 {
self.max_timer_id
}

pub fn set_max_timerid(&mut self, max: u64) {
self.max_timer_id = max;
}

fn get_next_timerid(&mut self) -> u64 {
let mut timer_id;
loop {
timer_id = self.next_timer_id;
if self.next_timer_id >= self.max_timer_id {
self.next_timer_id = 1;
} else {
self.next_timer_id = self.next_timer_id + 1;
}

if !self.map.contains_key(&timer_id) {
break;
}
}
timer_id
}

/// 添加定时器元素
Expand All @@ -140,14 +169,16 @@ impl<T: Timer> TimerRBTree<T> {
/// assert_eq!(timer.len(), 1);
/// }
pub fn add_timer(&mut self, val: T) -> u64 {
let timer_id = self.next_timer_id;
self.next_timer_id = self.next_timer_id.wrapping_add(1);
let timer_id = self.get_next_timerid();
self._add_timer(timer_id, val);
timer_id
}

fn _add_timer(&mut self, timer_id: u64, val: T) {
let when = val.when();
self.tree.insert(TreeKey(when, timer_id), val);
self.map.insert(timer_id, when);
timer_id
}

/// 删除指定的定时器,时间复杂度为O(logn),
///
/// # Examples
Expand Down Expand Up @@ -200,7 +231,7 @@ impl<T: Timer> TimerRBTree<T> {
/// let t = timer.add_timer(30);
/// *timer.get_mut_timer(&t).unwrap() = 33;
/// let val = timer.update_deltatime(30).unwrap();
/// assert_eq!(val, vec![33]);
/// assert_eq!(val.iter().map(|(_, v)| *v).collect::<Vec<usize>>(), vec![33]);
/// }
pub fn get_mut_timer(&mut self, timer_id: &u64) -> Option<&mut T> {
if let Some(when) = self.map.get(timer_id) {
Expand Down Expand Up @@ -237,17 +268,17 @@ impl<T: Timer> TimerRBTree<T> {
/// let mut timer = TimerRBTree::new();
/// timer.add_timer(30);
/// let val = timer.update_deltatime(30).unwrap();
/// assert_eq!(val, vec![30]);
/// assert_eq!(val.iter().map(|(_, v)| *v).collect::<Vec<usize>>(), vec![30]);
/// }
pub fn update_now(&mut self, now: u64) -> Option<Vec<T>> {
pub fn update_now(&mut self, now: u64) -> Option<Vec<(u64, T)>> {
self.cur_step = now;
let mut result = vec![];
loop {
if let Some(val) = self.tick_first() {
if self.cur_step < val {
break;
}
result.push(self.tree.pop_first().map(|(_, e)| e).unwrap());
result.push(self.tree.pop_first().map(|(k, e)| (k.1, e)).unwrap());
} else {
break;
}
Expand All @@ -264,9 +295,9 @@ impl<T: Timer> TimerRBTree<T> {
/// let mut timer = TimerRBTree::new();
/// timer.add_timer(30);
/// let val = timer.update_deltatime(30).unwrap();
/// assert_eq!(val, vec![30]);
/// assert_eq!(val, vec![(1, 30)]);
/// }
pub fn update_deltatime(&mut self, delta: u64) -> Option<Vec<T>> {
pub fn update_deltatime(&mut self, delta: u64) -> Option<Vec<(u64, T)>> {
self.update_now(self.cur_step.wrapping_add(delta))
}

Expand All @@ -280,32 +311,35 @@ impl<T: Timer> TimerRBTree<T> {
/// let mut timer = TimerRBTree::new();
/// timer.add_timer(30);
/// let mut idx = 0;
/// timer.update_deltatime_with_callback(30, &mut |_, v| {
/// let mut timer_id = 0;
/// timer.update_deltatime_with_callback(30, &mut |_, id, v| {
/// timer_id = id;
/// idx = v;
/// None
/// });
/// assert_eq!(timer_id, 1);
/// assert_eq!(idx, 30);
/// }
pub fn update_deltatime_with_callback<F>(&mut self, delta: u64, f: &mut F)
where
F: FnMut(&mut Self, T) -> Option<T>,
F: FnMut(&mut Self, u64, T) -> Option<(u64, T)>,
{
self.update_now_with_callback(self.cur_step.wrapping_add(delta), f)
}

pub fn update_now_with_callback<F>(&mut self, now: u64, f: &mut F)
where
F: FnMut(&mut Self, T) -> Option<T>,
F: FnMut(&mut Self, u64, T) -> Option<(u64, T)>,
{
if let Some(result) = self.update_now(now) {
let mut collect_result = vec![];
for r in result.into_iter() {
if let Some(v) = (*f)(self, r) {
if let Some(v) = (*f)(self, r.0, r.1) {
collect_result.push(v);
}
}
for v in collect_result.drain(..) {
self.add_timer(v);
for (timer_id, v) in collect_result.drain(..) {
self._add_timer(timer_id, v);
}
}
}
Expand Down
Loading

0 comments on commit 273ba6b

Please sign in to comment.