use std::mem;
use std::ops::IndexMut;
pub struct WheelTimer<T> {
max_interval: usize,
current_tick: usize,
size: usize,
ring: Vec<Vec<T>>
}
impl<T> Iterator for WheelTimer<T> {
type Item = Vec<T>;
fn next(&mut self) -> Option<Vec<T>> {
let size = self.size();
return if size > 0 {
Some(self.tick())
} else {
None
};
}
}
impl<T> WheelTimer<T> {
pub fn new(max_interval: usize) -> WheelTimer<T> {
let mut ring = Vec::with_capacity(max_interval);
for _ in 0..max_interval {
ring.push(Vec::new())
}
return WheelTimer{
max_interval: max_interval,
current_tick: 0,
ring: ring,
size: 0,
}
}
pub fn size(&self) -> usize {
self.size
}
pub fn schedule(&mut self, ticks: usize, value: T) {
let index = (self.current_tick + ticks) % self.max_interval;
self.ring.index_mut(index).push(value);
self.size = self.size + 1;
}
pub fn tick(&mut self) -> Vec<T> {
let node = mem::replace(self.ring.index_mut(self.current_tick), Vec::new());
self.current_tick = (self.current_tick + 1) % self.max_interval;
self.size = self.size - node.len();
return node
}
}