TimerList Data Structure
Relevant source files
This document provides detailed technical documentation of the TimerList
struct, which serves as the core data structure for managing timed events in the timer_list crate. It covers the internal min-heap architecture, public methods, performance characteristics, and implementation details.
For information about the TimerEvent
trait and event callback system, see TimerEvent System. For practical usage examples, see Usage Guide and Examples.
Core Structure Overview
The TimerList<E: TimerEvent>
struct provides an efficient priority queue implementation for managing timed events. It internally uses a binary heap data structure to maintain events in deadline order, enabling O(log n) insertions and O(1) access to the next expiring event.
Primary Components
flowchart TD subgraph subGraph0["Type Constraints"] TC["E: TimerEvent"] end TL["TimerList<E>"] BH["BinaryHeap<TimerEventWrapper<E>>"] TEW1["TimerEventWrapper<E>"] TEW2["TimerEventWrapper<E>"] TEW3["TimerEventWrapper<E>"] DL1["deadline: TimeValue"] EV1["event: E"] DL2["deadline: TimeValue"] EV2["event: E"] DL3["deadline: TimeValue"] EV3["event: E"] BH --> TEW1 BH --> TEW2 BH --> TEW3 TEW1 --> DL1 TEW1 --> EV1 TEW2 --> DL2 TEW2 --> EV2 TEW3 --> DL3 TEW3 --> EV3 TL --> BH TL --> TC
Sources: src/lib.rs(L30 - L32) src/lib.rs(L21 - L24)
The structure consists of three main components:
Component | Type | Purpose |
---|---|---|
TimerList | Public struct | Main interface for timer management |
BinaryHeap<TimerEventWrapper | Internal field | Heap storage for efficient ordering |
TimerEventWrapper | Internal struct | Wrapper containing deadline and event data |
Min-Heap Architecture
The TimerList
implements a min-heap through custom ordering logic on TimerEventWrapper<E>
. This ensures that events with earlier deadlines are always at the top of the heap for efficient retrieval.
Heap Ordering Implementation
flowchart TD subgraph subGraph2["Trait Implementations"] ORD["Ord"] PORD["PartialOrd"] EQT["Eq"] PEQ["PartialEq"] end subgraph subGraph1["Min-Heap Property"] ROOT["Earliest Deadline"] L1["Later Deadline"] R1["Later Deadline"] L2["Even Later"] R2["Even Later"] end subgraph subGraph0["TimerEventWrapper Ordering"] CMP["cmp()"] REV["other.deadline.cmp(&self.deadline)"] PCMP["partial_cmp()"] EQ["eq()"] COMP["self.deadline == other.deadline"] end CMP --> REV CMP --> ROOT EQ --> COMP EQT --> EQ L1 --> L2 L1 --> R2 ORD --> CMP PCMP --> CMP PEQ --> EQ PORD --> PCMP ROOT --> L1 ROOT --> R1
Sources: src/lib.rs(L34 - L52)
The ordering implementation uses reversed comparison logic:
Trait | Implementation | Purpose |
---|---|---|
Ord::cmp() | other.deadline.cmp(&self.deadline) | Reverses natural ordering for min-heap |
PartialOrd::partial_cmp() | Delegates tocmp() | Required for heap operations |
Eq/PartialEq::eq() | self.deadline == other.deadline | Deadline-based equality |
Public Methods
The TimerList
provides a clean API for timer management operations:
Core Operations
Method | Signature | Complexity | Purpose |
---|---|---|---|
new() | fn new() -> Self | O(1) | Creates empty timer list |
set() | fn set(&mut self, deadline: TimeValue, event: E) | O(log n) | Schedules new event |
expire_one() | fn expire_one(&mut self, now: TimeValue) -> Option<(TimeValue, E)> | O(log n) | Processes earliest expired event |
cancel() | fn cancel | O(n) | Removes events matching condition |
Query Operations
Method | Signature | Complexity | Purpose |
---|---|---|---|
is_empty() | fn is_empty(&self) -> bool | O(1) | Checks if any events exist |
next_deadline() | fn next_deadline(&self) -> Option | O(1) | Returns earliest deadline |
Sources: src/lib.rs(L54 - L100)
Internal Implementation Details
Event Scheduling Flow
sequenceDiagram participant Client as Client participant TimerList as TimerList participant BinaryHeap as BinaryHeap participant TimerEventWrapper as TimerEventWrapper Client ->> TimerList: "set(deadline, event)" TimerList ->> TimerEventWrapper: "TimerEventWrapper { deadline, event }" TimerList ->> BinaryHeap: "push(wrapper)" Note over BinaryHeap: "Auto-reorders via Ord trait" BinaryHeap -->> TimerList: "Heap maintains min property" TimerList -->> Client: "Event scheduled"
Sources: src/lib.rs(L69 - L71)
Event Expiration Flow
sequenceDiagram participant Client as Client participant TimerList as TimerList participant BinaryHeap as BinaryHeap Client ->> TimerList: "expire_one(now)" TimerList ->> BinaryHeap: "peek()" BinaryHeap -->> TimerList: "Some(earliest_wrapper)" alt "deadline <= now" TimerList ->> BinaryHeap: "pop()" BinaryHeap -->> TimerList: "TimerEventWrapper" TimerList -->> Client: "Some((deadline, event))" else "deadline > now" TimerList -->> Client: "None" end
Sources: src/lib.rs(L92 - L99)
Data Structure Memory Layout
The TimerList
maintains minimal memory overhead with efficient heap allocation:
flowchart TD subgraph subGraph1["Heap Properties"] HP1["Min-heap ordering"] HP2["O(log n) rebalancing"] HP3["Contiguous memory"] end subgraph subGraph0["Memory Layout"] TLS["TimerList Struct"] BHS["BinaryHeap Storage"] VEC["Vec<TimerEventWrapper>"] TEW1["TimerEventWrapper { deadline, event }"] TEW2["TimerEventWrapper { deadline, event }"] TEWN["..."] end BHS --> HP1 BHS --> HP2 BHS --> VEC TLS --> BHS VEC --> HP3 VEC --> TEW1 VEC --> TEW2 VEC --> TEWN
Sources: src/lib.rs(L30 - L32) src/lib.rs(L21 - L24)
Performance Characteristics
Operation | Time Complexity | Space Complexity | Notes |
---|---|---|---|
Insert (set) | O(log n) | O(1) additional | Binary heap insertion |
Peek next (next_deadline) | O(1) | O(1) | Heap root access |
Pop next (expire_one) | O(log n) | O(1) | Heap rebalancing required |
Cancel events | O(n) | O(n) | Linear scan with filtering |
Check empty | O(1) | O(1) | Heap size check |
The min-heap implementation provides optimal performance for the primary use case of sequential event processing by deadline order.
Sources: src/lib.rs(L54 - L100)