Add PriceLevel::snapshot_by_insertion_seq; bump to 0.8.1 (#102)#103
Merged
Conversation
Expose the resting orders in ascending insertion-sequence order — the exact order match_order/match_front consumes them — so a downstream pre-scan (e.g. self-trade prevention) can predict the sweep. The existing snapshot_orders() is (timestamp, sequence)-ordered and only equals the sweep when timestamps are monotonic with insertion; iter_orders() is unordered. Backed by a new OrderQueue::snapshot_by_seq (the ascending index walk already used by OrderQueue::Serialize, now factored out). Additive, non-breaking. Bumps version 0.8.0 -> 0.8.1.
There was a problem hiding this comment.
Pull request overview
Adds a new public accessor on PriceLevel to snapshot resting orders in pure insertion-sequence order, matching the traversal/consumption order used by match_order (and diverging from timestamp-based ordering when timestamps are non-monotonic with insertion).
Changes:
- Add
PriceLevel::snapshot_by_insertion_seq()as a public,#[must_use]accessor returning orders in ascending insertion sequence. - Factor out the underlying index-walk into
OrderQueue::snapshot_by_seq()and reuse it fromimpl Serialize for OrderQueueto avoid duplication. - Add targeted regression tests for insertion-sequence snapshot behavior (including non-monotonic timestamps) and bump crate version to
0.8.1.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/price_level/level.rs | Adds snapshot_by_insertion_seq() with documentation contrasting it vs existing order views. |
| src/price_level/order_queue.rs | Implements snapshot_by_seq() (index walk) and reuses it in Serialize impl. |
| src/price_level/tests/level.rs | Adds regression tests asserting snapshot order matches match_order maker consumption order. |
| Cargo.toml | Bumps package version from 0.8.0 to 0.8.1. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PriceLevelexposed two order views, neither of which matches the ordermatch_orderactually consumes liquidity:iter_orders()—DashMap-backed, non-stable order.snapshot_orders()— sorted by(timestamp, sequence).match_order→OrderQueue::match_front()— consumes by pure insertionsequence.
snapshot_orders()equals the sweep order only when timestamps are monotonicwith insertion (client-supplied / modify-restamped timestamps break that), so a
downstream self-trade-prevention pre-scan had no public primitive to predict the
sweep (issue #102). This adds one.
Changes
PriceLevel::snapshot_by_insertion_seq() -> Vec<Arc<OrderType<()>>>(
#[must_use]) — resting orders in ascending insertion sequence, i.e. the exactorder
match_orderconsumes them. Doc contrasts it withsnapshot_orders()(timestamp order) and
iter_orders()(unordered), and notes the samepoint-in-time caveat as
snapshot_orders().OrderQueue::snapshot_by_seq()(pub(crate)) — the ascendingindex(
SkipMap<seq, Id>) walk thatmatch_frontuses; factored out of the existingimpl Serialize for OrderQueue(which now calls it — no duplication).No new exported type, no
lib.rs/prelude.rschange, no migration guide, nosnapshot-format change, no
match_ordersemantics change.Testing
test_snapshot_by_insertion_seq_matches_match_order_consumption— withnon-monotonic timestamps (id 1 inserted first but timestamped later than id
2): asserts the accessor yields insertion order
[1, 2], equals the maker-idorder
match_orderactually emits, and differs fromsnapshot_orders()(
[2, 1]) — proving it predicts the sweep wheresnapshot_orders()does not._empty_level,_partial_fill_keeps_front(KeepInPlace, same seq),_replenished_maker_moves_to_tail(ReplaceAtTail → new seq → last).cargo test: 412 (lib) + 9 proptest + 1 integration + 9 doc, 0 failed.cargo clippy --all-targets --all-features -- -D warnings,cargo fmt --all --check,cargo build --release,make doc(rustdoc-D warnings): all clean.Checklist
Serializeindex-walk# Errors(returnsVec);#[must_use]; doc'd vs the other two viewsCloses #102