Skip to main content

PreTradeLock

Struct PreTradeLock 

Source
pub struct PreTradeLock { /* private fields */ }
Expand description

Stable lock context captured during pre-trade reservation.

PreTradeLock is not just a copy of request input. It is the serialized context of what the engine actually reserved and how that reservation must later be reconciled.

A lock groups (group_id, price) records under their group identifier. Pushing several prices for the same group accumulates them in insertion order; the resulting list is what Self::prices_of returns.

The lock context must travel together with the order lifecycle. If a policy relies on execution report fill details to reconcile the reservation, the lock produced during pre-trade must be stored until the final execution report for that order has been processed. Dropping it too early breaks the engine’s ability to correctly unlock the unused remainder or finalize the reserved state using the same assumptions that were applied when the order was accepted.

§Performance

In practice the overwhelming majority of orders carry only prices for DEFAULT_POLICY_GROUP_ID. The internal storage keeps the default group in a dedicated inline-capacity slot, so the hot path neither scans nor allocates. Non-default groups are stored in a second inline-capacity list of sections, each section grouping prices for one group identifier. Reads, writes, and lookups for the default group are O(1); operations for non-default groups scan the small sections list once.

The concrete representation is intentionally private. Construct values through the provided constructors and inspect them through the returned iterators. This keeps the type free to evolve its internal layout without affecting cross-language bindings.

§Serialization

With the serde feature enabled the lock uses an extremely compact wire format that emits nothing the receiver does not need:

  • no field names, no map keys, no struct tags;
  • the default group identifier is implicit (it is the first sublist);
  • non-default groups are sent once with all their prices, never repeating the group identifier.

The on-wire shape is a sequence of sublists. The first sublist is the list of prices for DEFAULT_POLICY_GROUP_ID (it may be empty). Every following sublist describes one non-default group: its first element is the u16 group identifier, the remaining elements are the prices stored for that group.

Because the format only uses serialize_seq, the same compactness applies to every self-describing serde format: JSON (the canonical FFI exchange format), MessagePack (rmp-serde), CBOR (ciborium), BSON, YAML (serde_yaml), TOML, RON, Apache Avro, and FlexBuffers. Rust-only formats such as Bincode and postcard work too but remain outside the cross-language compatibility contract. The format-specific overhead per sublist is the array header only (one byte for short arrays in MessagePack/CBOR, two characters [ and ] in JSON), so the wire size is dominated by the Price encoding itself.

Same lock, three formats:

// a default-only lock with a single price 185
JSON         [["185"]]                         // 9 bytes
MessagePack  91 91 a3 31 38 35                 // 6 bytes (hex)
CBOR         81 81 63 31 38 35                 // 6 bytes (hex)

// a mixed lock: default 185, group 7 with two prices 200 and 201
JSON         [["185"],[7,"200","201"]]         // 25 bytes
MessagePack  92 91 a3 31 38 35 93 07 a3 32 30
             30 a3 32 30 31                    // 16 bytes (hex)
CBOR         82 81 63 31 38 35 83 07 63 32 30
             30 63 32 30 31                    // 16 bytes (hex)

// empty lock
JSON         []                                // 2 bytes
MessagePack  90                                // 1 byte
CBOR         80                                // 1 byte

Implementations§

Source§

impl PreTradeLock

Source

pub fn new() -> Self

Creates an empty lock context.

Source

pub fn len(&self) -> usize

Returns the number of stored price entries.

Source

pub fn is_empty(&self) -> bool

Returns true when no price entries are stored.

Source

pub fn from_entries<EntriesIter>(entries: EntriesIter) -> Self
where EntriesIter: IntoIterator<Item = (PolicyGroupId, Price)>,

Creates a lock context populated from the given (group_id, price) records.

Records with the same group_id are merged in insertion order, just like repeated Self::push calls.

Source

pub fn push(&mut self, policy_group_id: PolicyGroupId, price: Price)

Stores price under policy_group_id.

Prices already stored under the same policy_group_id are preserved; the new price is appended to the end of that group’s list.

Source

pub fn push_many<PricesIter>( &mut self, policy_group_id: PolicyGroupId, prices: PricesIter, )
where PricesIter: IntoIterator<Item = Price>, PricesIter::IntoIter: ExactSizeIterator,

Stores every price under policy_group_id, preserving any prices already stored under the same group.

Target capacity is computed up-front from the iterator’s exact length, so the destination storage grows at most once regardless of how many prices are pushed.

Source

pub fn merge(&mut self, other: &Self)

Appends all entries from other into self.

Prices for the default group are bulk-copied in one operation. For each non-default group in other, prices are bulk-copied into the matching existing section or into a new section if none exists yet.

The hot path — a single-entry lock merging into an existing one — costs exactly one extend_from_slice call with no iteration or allocation.

Source

pub fn entries(&self) -> Entries<'_>

Iterates over every (group_id, price) pair, default-group prices first, then each non-default group in insertion order.

Source

pub fn prices_of(&self, policy_group_id: PolicyGroupId) -> PricesByGroup<'_>

Iterates over every price stored under policy_group_id, in insertion order.

Default-group lookups are O(1); non-default lookups scan the section list once. Both return cheap iterators that walk an inline-storage slice with no allocation.

Trait Implementations§

Source§

impl Clone for PreTradeLock

Source§

fn clone(&self) -> PreTradeLock

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PreTradeLock

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for PreTradeLock

Source§

fn default() -> PreTradeLock

Returns the “default value” for a type. Read more
Source§

impl Eq for PreTradeLock

Source§

impl Extend<(PolicyGroupId, Price)> for PreTradeLock

Source§

fn extend<EntriesIter>(&mut self, iter: EntriesIter)
where EntriesIter: IntoIterator<Item = (PolicyGroupId, Price)>,

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl FromIterator<(PolicyGroupId, Price)> for PreTradeLock

Source§

fn from_iter<EntriesIter>(iter: EntriesIter) -> Self
where EntriesIter: IntoIterator<Item = (PolicyGroupId, Price)>,

Creates a value from an iterator. Read more
Source§

impl PartialEq for PreTradeLock

Source§

fn eq(&self, other: &PreTradeLock) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for PreTradeLock

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.