Low-Level API
Relevant source files
This page documents the unsafe, low-level API provided by the RawList<G: GetLinks> interface for advanced users who need direct control over memory management and performance-critical operations. This layer operates with raw pointers and requires careful attention to memory safety invariants.
For safe ownership management and wrapper abstractions, see Advanced API. For the user-friendly macro-generated interface, see User-Friendly API.
Core Types and Traits
The low-level API is built around three primary types that work together to provide intrusive linked list functionality.
GetLinks Trait
The GetLinks trait serves as the fundamental abstraction that allows any type to be stored in a linked list by providing access to embedded link fields.
flowchart TD
subgraph subGraph1["Implementation Requirements"]
UserStruct["User Struct(contains Links field)"]
LinksField["links: Links"]
ImplBlock["impl GetLinksfor UserStruct"]
end
subgraph subGraph0["GetLinks Trait System"]
GetLinksTrait["GetLinkstrait"]
EntryType["type EntryType: ?Sized"]
GetLinksMethod["get_links(&EntryType)-> &Links"]
end
GetLinksMethod --> LinksField
GetLinksTrait --> EntryType
GetLinksTrait --> GetLinksMethod
ImplBlock --> GetLinksTrait
UserStruct --> ImplBlock
UserStruct --> LinksField
Core GetLinks Implementation Pattern
The trait defines two key components: an associated type EntryType that represents the type of objects stored in the list, and a method get_links() that returns a reference to the embedded Links<T> structure.
Sources: src/raw_list.rs(L23 - L29)
Links Structure
The Links<T> structure contains the actual linked list pointers and provides atomic insertion tracking to prevent double-insertion and enable constant-time removal.
flowchart TD
subgraph subGraph2["Atomic Operations"]
AcquireInsert["acquire_for_insertion()compare_exchange(false, true)"]
ReleaseRemove["release_after_removal()store(false, Release)"]
end
subgraph subGraph1["ListEntry Contents"]
NextPtr["next: Option>"]
PrevPtr["prev: Option>"]
end
subgraph subGraph0["Links Memory Layout"]
LinksStruct["Links"]
InsertedFlag["inserted: AtomicBool(tracks insertion state)"]
EntryCell["entry: UnsafeCell>(contains pointers)"]
end
EntryCell --> NextPtr
EntryCell --> PrevPtr
InsertedFlag --> AcquireInsert
InsertedFlag --> ReleaseRemove
LinksStruct --> EntryCell
LinksStruct --> InsertedFlag
Atomic Insertion Tracking
The inserted field uses atomic compare-and-swap operations to ensure thread-safe insertion tracking. The acquire_for_insertion() method attempts to atomically change the state from false to true, preventing double-insertion.
Sources: src/raw_list.rs(L35 - L66) src/raw_list.rs(L74 - L86)
RawList Structure
The RawList<G: GetLinks> provides the core linked list operations using raw pointer manipulation.
flowchart TD
subgraph subGraph3["Iteration Support"]
Iter["iter() -> Iterator"]
CursorFront["cursor_front_mut()-> CursorMut"]
end
subgraph subGraph2["Query Operations"]
IsEmpty["is_empty() -> bool"]
Front["front() -> Option>"]
Back["back() -> Option>"]
end
subgraph subGraph1["Primary Operations"]
PushBack["push_back(&EntryType)-> bool"]
PushFront["push_front(&EntryType)-> bool"]
Remove["remove(&EntryType)-> bool"]
PopFront["pop_front()-> Option>"]
InsertAfter["insert_after(&existing, &new)-> bool"]
end
subgraph subGraph0["RawList"]
RawListStruct["RawList"]
HeadPtr["head: Option>"]
end
RawListStruct --> Back
RawListStruct --> CursorFront
RawListStruct --> Front
RawListStruct --> HeadPtr
RawListStruct --> InsertAfter
RawListStruct --> IsEmpty
RawListStruct --> Iter
RawListStruct --> PopFront
RawListStruct --> PushBack
RawListStruct --> PushFront
RawListStruct --> Remove
Sources: src/raw_list.rs(L88 - L284)
List Operations
Insertion Operations
The RawList provides several insertion methods that work with raw references and return boolean values indicating success or failure.
| Operation | Method | Safety Requirements | Return Value |
|---|---|---|---|
| Back Insertion | push_back(&EntryType) | Reference must remain valid while on list | bool- true if inserted, false if already on list |
| Front Insertion | push_front(&EntryType) | Reference must remain valid while on list | bool- true if inserted, false if already on list |
| Positional Insertion | insert_after(&existing, &new) | Both references valid, existing must be on list | bool- true if inserted, false if new already on list |
Insertion Safety Model
All insertion operations use the atomic acquire_for_insertion() mechanism to prevent double-insertion. The operations are marked unsafe because the caller must ensure reference validity for the lifetime of list membership.
Sources: src/raw_list.rs(L153 - L197) src/raw_list.rs(L135 - L151)
Removal Operations
Removal operations provide constant-time complexity by updating surrounding pointers directly without traversal.
flowchart TD
subgraph subGraph0["Removal Process"]
CheckInsertion["Check insertion state(entry.next != None)"]
UpdatePointers["Update prev.nextand next.prev"]
UpdateHead["Update head ifremoving head element"]
ResetLinks["Reset entry.nextand entry.prev to None"]
ReleaseState["release_after_removal()store(false, Release)"]
end
CheckInsertion --> UpdatePointers
ResetLinks --> ReleaseState
UpdateHead --> ResetLinks
UpdatePointers --> UpdateHead
Constant-Time Removal Implementation
The remove_internal() method achieves O(1) complexity by directly accessing the target element's links rather than traversing the list. The atomic release operation ensures thread-safe state management.
Sources: src/raw_list.rs(L199 - L245) src/raw_list.rs(L247 - L257)
Cursor System
The cursor system provides controlled traversal and modification capabilities for the linked list.
Cursor Types
| Cursor Type | Mutability | Capabilities |
|---|---|---|
| Cursor<'a, G> | Immutable | Read-only traversal, element inspection |
| CursorMut<'a, G> | Mutable | Traversal, element modification, removal |
Cursor Operations
flowchart TD
subgraph subGraph2["Mutable Cursor"]
CursorMut["CursorMut<'a, G>"]
CurrentMut["current() -> Option<&mut EntryType>"]
RemoveCurrent["remove_current()-> Option>"]
PeekNext["peek_next() -> Option<&mut EntryType>"]
PeekPrev["peek_prev() -> Option<&mut EntryType>"]
end
subgraph subGraph1["Read-Only Cursor"]
Cursor["Cursor<'a, G>"]
Current["current() -> Option<&EntryType>"]
end
subgraph subGraph0["Cursor Navigation"]
CommonCursor["CommonCursor"]
MoveNext["move_next(&RawList)"]
MovePrev["move_prev(&RawList)"]
CurrentPos["cur: Option>"]
end
CommonCursor --> CurrentPos
CommonCursor --> MoveNext
CommonCursor --> MovePrev
Cursor --> CommonCursor
Cursor --> Current
CursorMut --> CommonCursor
CursorMut --> CurrentMut
CursorMut --> PeekNext
CursorMut --> PeekPrev
CursorMut --> RemoveCurrent
Cursor Safety Model
Cursors maintain lifetime relationships with the underlying list to prevent use-after-free scenarios. The mutable cursor provides safe removal operations that automatically advance the cursor position.
Sources: src/raw_list.rs(L339 - L423) src/raw_list.rs(L286 - L329)
Iterator Implementation
The iterator system provides both forward and backward traversal capabilities.
Iterator Structure
flowchart TD
subgraph subGraph2["IntoIterator Support"]
IntoIter["impl IntoIterator for &RawListinto_iter() -> Iterator"]
end
subgraph subGraph1["Iterator Traits"]
StdIterator["impl Iteratornext() -> Option<&EntryType>"]
DoubleEnded["impl DoubleEndedIteratornext_back() -> Option<&EntryType>"]
end
subgraph subGraph0["Iterator Implementation"]
IteratorStruct["Iterator<'a, G>"]
CursorFront["cursor_front: Cursor<'a, G>"]
CursorBack["cursor_back: Cursor<'a, G>"]
end
IntoIter --> IteratorStruct
IteratorStruct --> CursorBack
IteratorStruct --> CursorFront
IteratorStruct --> DoubleEnded
IteratorStruct --> StdIterator
Bidirectional Iteration
The iterator uses two cursors to enable efficient bidirectional traversal, supporting both Iterator and DoubleEndedIterator traits for compatibility with standard Rust iteration patterns.
Sources: src/raw_list.rs(L434 - L464) src/raw_list.rs(L425 - L431)
Memory Layout and Safety Invariants
Thread Safety Model
The RawList implements thread safety through atomic operations and careful ordering constraints.
| Component | Thread Safety Mechanism | Ordering |
|---|---|---|
| Insertion Tracking | AtomicBoolwith compare-exchange | Acquireon insert,Relaxedon failure |
| Removal State | AtomicBoolstore operation | Releaseordering |
| Pointer Access | UnsafeCellwith controlled access | Synchronized through insertion state |
Safety Invariants
- Link Ownership: Once successfully inserted, the list owns the links until removal
- Reference Validity: Callers must ensure references remain valid while on the list
- Single List Membership: An element can only be on one list at a time (enforced by atomic insertion tracking)
- Removal Safety: Only elements currently on the list may be removed
Sources: src/raw_list.rs(L40 - L46) src/raw_list.rs(L331 - L337)
Memory Layout Diagram
flowchart TD
subgraph subGraph3["List Head"]
RawListHead["RawList.headOption>"]
end
subgraph subGraph2["ListEntry Pointers"]
NextPointer["next: Option>(8 bytes on 64-bit)"]
PrevPointer["prev: Option>(8 bytes on 64-bit)"]
end
subgraph subGraph1["Links Internal Layout"]
AtomicBool["inserted: AtomicBool(1 byte + padding)"]
UnsafeCell["entry: UnsafeCell(contains raw pointers)"]
end
subgraph subGraph0["Node Memory Structure"]
UserData["User Data Fields(application-specific)"]
LinksField["links: Links"]
end
LinksField --> AtomicBool
LinksField --> UnsafeCell
NextPointer --> UserData
PrevPointer --> UserData
RawListHead --> UserData
UnsafeCell --> NextPointer
UnsafeCell --> PrevPointer
UserData --> LinksField
Sources: src/raw_list.rs(L35 - L38) src/raw_list.rs(L74 - L77) src/raw_list.rs(L93 - L95)