Skip to main content

perpl_sdk/state/l3_book/
level.rs

1//! L3 price level with linked list of orders.
2
3use fastnum::UD64;
4
5use crate::types;
6
7/// Price level containing orders in a doubly-linked list (FIFO order).
8///
9/// The level stores head/tail pointers to the linked list and maintains
10/// cached aggregates for O(1) access to total size and order count.
11#[derive(Clone, derive_more::Debug, Default)]
12pub struct BookLevel {
13    /// First order in the FIFO queue (oldest).
14    head: Option<types::OrderId>,
15    /// Last order in the FIFO queue (newest).
16    tail: Option<types::OrderId>,
17    /// Cached aggregate: total size at this level.
18    #[debug("{cached_size}")]
19    cached_size: UD64,
20    /// Cached aggregate: number of orders at this level.
21    cached_count: u32,
22}
23
24impl BookLevel {
25    /// Create a new empty book level.
26    pub fn new() -> Self { Self::default() }
27
28    /// Total size at this price level, excluding expired orders (cached, O(1)).
29    pub fn size(&self) -> UD64 { self.cached_size }
30
31    /// Number of orders at this price level, excluding expired orders (cached,
32    /// O(1)).
33    pub fn num_orders(&self) -> u32 { self.cached_count }
34
35    /// Check if this level has no orders.
36    pub fn is_empty(&self) -> bool { self.head.is_none() }
37
38    /// First (oldest) order ID at this level.
39    pub(crate) fn head(&self) -> Option<types::OrderId> { self.head }
40
41    /// Last (newest) order ID at this level.
42    pub(crate) fn tail(&self) -> Option<types::OrderId> { self.tail }
43
44    /// Set the head pointer.
45    pub(crate) fn set_head(&mut self, head: Option<types::OrderId>) { self.head = head; }
46
47    /// Set the tail pointer.
48    pub(crate) fn set_tail(&mut self, tail: Option<types::OrderId>) { self.tail = tail; }
49
50    /// Add to cached size.
51    pub(crate) fn add_size(&mut self, size: UD64) {
52        self.cached_size += size;
53        self.cached_count += 1;
54    }
55
56    /// Subtract from cached size.
57    pub(crate) fn sub_size(&mut self, size: UD64) {
58        self.cached_size -= size;
59        self.cached_count -= 1;
60    }
61
62    /// Update cached size (for size changes without count change).
63    pub(crate) fn update_size(&mut self, old_size: UD64, new_size: UD64) {
64        self.cached_size -= old_size;
65        self.cached_size += new_size;
66    }
67}