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:

ComponentTypePurpose
TimerListPublic structMain interface for timer management
BinaryHeap<TimerEventWrapper>Internal fieldHeap storage for efficient ordering
TimerEventWrapperInternal structWrapper 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:

TraitImplementationPurpose
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.deadlineDeadline-based equality

Public Methods

The TimerList provides a clean API for timer management operations:

Core Operations

MethodSignatureComplexityPurpose
new()fn new() -> SelfO(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(&mut self, condition: F)O(n)Removes events matching condition

Query Operations

MethodSignatureComplexityPurpose
is_empty()fn is_empty(&self) -> boolO(1)Checks if any events exist
next_deadline()fn next_deadline(&self) -> OptionO(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

OperationTime ComplexitySpace ComplexityNotes
Insert (set)O(log n)O(1) additionalBinary 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 eventsO(n)O(n)Linear scan with filtering
Check emptyO(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)