#include <vector>
#include <list>
#include <functional>
#include <unordered_map>
#include <iostream>
class TimerWheel {
public:
typedef std::function<void()> TimerCallback;
typedef std::size_t TimerId;
TimerWheel(int tick, int wheelSize)
: tick_(tick), wheelSize_(wheelSize), currentTick_(0), wheel_(wheelSize_), nextId_(0) {}
TimerId addTimer(int delay, TimerCallback cb) {
int ticks = delay / tick_;
int index = (currentTick_ + ticks) % wheelSize_;
TimerId id = nextId_++;
wheel_[index].push_back({ticks, cb, id});
idMap_[id] = {index, --wheel_[index].end()};
return id;
}
void removeTimer(TimerId id) {
auto it = idMap_.find(id);
if (it != idMap_.end()) {
wheel_[it->second.first].erase(it->second.second);
idMap_.erase(it);
}
}
void tick() {
auto& slot = wheel_[currentTick_];
for (auto it = slot.begin(); it != slot.end();) {
if (--it->first == 0) {
it->second();
it = slot.erase(it);
} else {
++it;
}
}
currentTick_ = (currentTick_ + 1) % wheelSize_;
}
private:
struct Timer {
int ticks;
TimerCallback callback;
TimerId id;
};
int tick_;
int wheelSize_;
int currentTick_;
TimerId nextId_;
std::vector<std::list<Timer>> wheel_;
std::unordered_map<TimerId, std::pair<int, std::list<Timer>::iterator>> idMap_;
};
测试代码:
void test1() {
TimerWheel tw(1, 5);
tw.addTimer(1, [](){ std::cout << "Timer 1 fired\n"; });
tw.addTimer(2, [](){ std::cout << "Timer 2 fired\n"; });
tw.addTimer(3, [](){ std::cout << "Timer 3 fired\n"; });
for (int i = 0; i < 5; ++i) {
tw.tick();
}
// Output:
// Timer 1 fired
// Timer 2 fired
// Timer 3 fired
}
void test2() {
TimerWheel tw(1, 5);
auto id = tw.addTimer(2, [](){ std::cout << "This should not be printed\n"; });
tw.removeTimer(id);
for (int i = 0; i < 5; ++i) {
tw.tick();
}
// Output: (nothing)
}
void test3() {
TimerWheel tw(1, 5);
tw.addTimer(5, [](){ std::cout << "Timer 1 fired\n"; });
tw.addTimer(10, [](){ std::cout << "Timer 2 fired\n"; });
for (int i = 0; i < 15; ++i) {
tw.tick();
}
// Output:
// Timer 1 fired
// Timer 2 fired
}
int main() {
test1();
test2();
test3();
return 0;
}