3 unstable releases

Uses old Rust 2015

0.2.0 Feb 1, 2018
0.1.1 Oct 10, 2016
0.1.0 Oct 10, 2016

#38 in #timer

30 downloads per month
Used in rabble


488 lines

Build Status

API Documentation


Add the following to your Cargo.toml

ferris = "0.1"

Add this to your crate root

extern crate ferris;


Ferris consists of two concrete hierarchical timer wheels. Each has multiple inner wheels with different resolutions to provide a large time range with minimal memory use.

There is an allocating wheel that allocates each timer on the heap and a copying wheel that doesn't. Which one you use is simply a matter of preference and benchmarking in your specific application.

Start and Stop are O(1) operations. Expiry is O(n) on the number of elements in the slot.


A hierarchical timer wheel

The number of wheels in the hierarchy are determined by the number of Resolutions passed into the concrete constructors AllocWheel::new() and CopyWheel::new(). The size of each wheel is automatically determined based on whether certain other resolutions are available. For instance if a wheel is constructed consisting of Resolution::TenMs and Resolution::HundredMs, then the number of slots in the 10 ms wheel will be 10 (10 slots to get to 100ms). However, if Resolution::HundredMs was not used, then Resolution::TenMs would have 100 slots (100ms to get to 1 sec).

In order for the timer to operate correctly, it must tick at the maximum resolution. For instance if 10ms and 1s resolutions are used, expire() must be called every 10ms.

The minimum length of a timer is limited by the highest resolution. For instance if 10ms and 1s resolutions were used, the minimum length of a timer would be 10ms.

The maximum length of a timer is limited by the lowest resolution. For instance if 10ms, and 1s resolutions were used, the maximum length of a timer would be 59s.

There is no migration between wheels. A timer is assigned to a single wheel and is scheduled at it's minimum resolution. E.g. If a timer is scheduled for 1.3s it will be scheduled to fire 2 second ticks later. This is most useful for coarse grain timers, is more efficient computationally and uses less memory than being more precise. The wheels don't have to keep track of offsets for the next inner wheel for wheel to wheel migration, and thus save memory. And since the migration ddoesn't actually occur, we save cpu, and potentially extra allocations.

No runtime deps