VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
wheel_timer.h File Reference

Hash-wheel timer for managing large numbers of concurrent timeouts efficiently. More...

#include <cstdint>
#include <functional>
#include <memory>
#include "./macros.h"
Include dependency graph for wheel_timer.h:

Go to the source code of this file.

Classes

 O(1) hash-wheel timer backed by a fixed-size circular slot array. More...

Namespaces

Detailed Description

Hash-wheel timer for managing large numbers of concurrent timeouts efficiently.

WheelTimer implements a hashed timing wheel – a classic data structure for O(1) timer insertion, removal and expiry checking. It is appropriate when hundreds to hundreds of thousands of independent timeouts must be tracked simultaneously, such as in a session manager or a connection-pool keep-alive system.

Algorithm:

  • The wheel contains slots evenly-spaced time buckets.
  • Each tick advances the wheel by one slot; the advance period is interval_ms.
  • Timeouts longer than slots * interval_ms are stored with a round counter and skipped until the counter reaches zero.
  • Adding a timer is O(1). Removal is O(1) via the internal key-to-slot index.
  • Expiry detection per tick is O(k) where k is the number of handlers in the current slot.

Lifecycle:

  1. Construct with WheelTimer(slots, interval_ms).
  2. Call start() to launch the background worker thread.
  3. Add timers with add(); store the returned Key for later removal.
  4. Call stop() to terminate the background thread.
Note
  • Expired callbacks are invoked from the internal worker thread. Use thread-safe structures or post results to a MessageLoop inside the callback.
  • set_catchup_limit() controls how many missed slots are processed in one tick to prevent a long stall from causing a burst of expired callbacks.
Example
// 256 slots, 10 ms per slot -> max 2.56 s without wrapping; higher durations use rounds.
vlink::WheelTimer wheel(256, 10);
wheel.start();
auto key = wheel.add(1000, [](vlink::WheelTimer::Key k) {
// fired after ~1000 ms
});
// Repeating every 500 ms:
auto repeat_key = wheel.add(500, [](vlink::WheelTimer::Key k) {}, 500);
wheel.remove(key); // cancel before expiry
wheel.stop();