Skip to content

Commit 8e39195

Browse files
authored
Merge pull request #28 from joaquinbejar/issue-19-introduce-value-newtypes
refactor: introduce Price/Quantity/TimestampMs value newtypes across public API
2 parents 5687b9c + a84646d commit 8e39195

27 files changed

Lines changed: 1039 additions & 779 deletions

‎benches/concurrent/contention.rs‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use criterion::{BenchmarkId, Criterion};
22
use pricelevel::{
3-
Hash32, Id, OrderType, OrderUpdate, PriceLevel, Side, TimeInForce, UuidGenerator,
3+
Hash32, Id, OrderType, OrderUpdate, Price, PriceLevel, Quantity, Side, TimeInForce,
4+
TimestampMs, UuidGenerator,
45
};
56
use std::sync::{Arc, Barrier};
67
use std::thread;
@@ -210,7 +211,7 @@ fn measure_hot_spot_contention(
210211
// Update quantity
211212
let _ = thread_price_level.update_order(OrderUpdate::UpdateQuantity {
212213
order_id: Id::from_u64(order_idx),
213-
new_quantity: 15,
214+
new_quantity: Quantity::new(15),
214215
});
215216
}
216217
_ => {
@@ -247,11 +248,11 @@ fn measure_hot_spot_contention(
247248
fn create_standard_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
248249
OrderType::Standard {
249250
id: Id::from_u64(id),
250-
price,
251-
quantity,
251+
price: Price::new(price),
252+
quantity: Quantity::new(quantity),
252253
side: Side::Buy,
253254
user_id: Hash32::zero(),
254-
timestamp: 1616823000000,
255+
timestamp: TimestampMs::new(1616823000000),
255256
time_in_force: TimeInForce::Gtc,
256257
extra_fields: (),
257258
}

‎benches/concurrent/register.rs‎

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use criterion::{BenchmarkId, Criterion, criterion_group};
22
use pricelevel::{
3-
Hash32, Id, OrderType, OrderUpdate, PegReferenceType, PriceLevel, Side, TimeInForce,
4-
UuidGenerator,
3+
Hash32, Id, OrderType, OrderUpdate, PegReferenceType, Price, PriceLevel, Quantity, Side,
4+
TimeInForce, TimestampMs, UuidGenerator,
55
};
66
use std::sync::{Arc, Barrier};
77
use std::thread;
@@ -318,7 +318,7 @@ fn measure_concurrent_mixed_operations(thread_count: usize, iterations: u64) ->
318318
let base_id = thread_id as u64 * 1_000_000 + (i - 1);
319319
let _ = thread_price_level.update_order(OrderUpdate::UpdateQuantity {
320320
order_id: Id::from_u64(base_id),
321-
new_quantity: 20,
321+
new_quantity: Quantity::new(20),
322322
});
323323
}
324324
}
@@ -351,11 +351,11 @@ fn measure_concurrent_mixed_operations(thread_count: usize, iterations: u64) ->
351351
fn create_standard_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
352352
OrderType::Standard {
353353
id: Id::from_u64(id),
354-
price,
355-
quantity,
354+
price: Price::new(price),
355+
quantity: Quantity::new(quantity),
356356
side: Side::Buy,
357357
user_id: Hash32::zero(),
358-
timestamp: 1616823000000,
358+
timestamp: TimestampMs::new(1616823000000),
359359
time_in_force: TimeInForce::Gtc,
360360
extra_fields: (),
361361
}
@@ -365,12 +365,12 @@ fn create_standard_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
365365
fn create_iceberg_order(id: u64, price: u128, visible: u64, hidden: u64) -> OrderType<()> {
366366
OrderType::IcebergOrder {
367367
id: Id::from_u64(id),
368-
price,
369-
visible_quantity: visible,
370-
hidden_quantity: hidden,
368+
price: Price::new(price),
369+
visible_quantity: Quantity::new(visible),
370+
hidden_quantity: Quantity::new(hidden),
371371
side: Side::Buy,
372372
user_id: Hash32::zero(),
373-
timestamp: 1616823000000,
373+
timestamp: TimestampMs::new(1616823000000),
374374
time_in_force: TimeInForce::Gtc,
375375
extra_fields: (),
376376
}
@@ -380,11 +380,11 @@ fn create_iceberg_order(id: u64, price: u128, visible: u64, hidden: u64) -> Orde
380380
fn create_post_only_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
381381
OrderType::PostOnly {
382382
id: Id::from_u64(id),
383-
price,
384-
quantity,
383+
price: Price::new(price),
384+
quantity: Quantity::new(quantity),
385385
side: Side::Buy,
386386
user_id: Hash32::zero(),
387-
timestamp: 1616823000000,
387+
timestamp: TimestampMs::new(1616823000000),
388388
time_in_force: TimeInForce::Gtc,
389389
extra_fields: (),
390390
}
@@ -402,15 +402,15 @@ fn create_reserve_order(
402402
) -> OrderType<()> {
403403
OrderType::ReserveOrder {
404404
id: Id::from_u64(id),
405-
price,
406-
visible_quantity: visible,
407-
hidden_quantity: hidden,
405+
price: Price::new(price),
406+
visible_quantity: Quantity::new(visible),
407+
hidden_quantity: Quantity::new(hidden),
408408
side: Side::Buy,
409409
user_id: Hash32::zero(),
410-
timestamp: 1616823000000,
410+
timestamp: TimestampMs::new(1616823000000),
411411
time_in_force: TimeInForce::Gtc,
412-
replenish_threshold: threshold,
413-
replenish_amount,
412+
replenish_threshold: Quantity::new(threshold),
413+
replenish_amount: replenish_amount.map(Quantity::new),
414414
auto_replenish,
415415
extra_fields: (),
416416
}
@@ -420,11 +420,11 @@ fn create_reserve_order(
420420
fn create_pegged_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
421421
OrderType::PeggedOrder {
422422
id: Id::from_u64(id),
423-
price,
424-
quantity,
423+
price: Price::new(price),
424+
quantity: Quantity::new(quantity),
425425
side: Side::Buy,
426426
user_id: Hash32::zero(),
427-
timestamp: 1616823000000,
427+
timestamp: TimestampMs::new(1616823000000),
428428
time_in_force: TimeInForce::Gtc,
429429
reference_price_offset: -50,
430430
reference_price_type: PegReferenceType::BestAsk,
@@ -439,11 +439,11 @@ fn setup_standard_orders(order_count: u64) -> PriceLevel {
439439
for i in 0..order_count {
440440
let order = OrderType::Standard {
441441
id: Id::from_u64(i),
442-
price: 10000u128,
443-
quantity: 10,
442+
price: Price::new(10000),
443+
quantity: Quantity::new(10),
444444
side: Side::Buy,
445445
user_id: Hash32::zero(),
446-
timestamp: 1616823000000 + i,
446+
timestamp: TimestampMs::new(1616823000000 + i),
447447
time_in_force: TimeInForce::Gtc,
448448
extra_fields: (),
449449
};

‎benches/price_level/add_orders.rs‎

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use criterion::{BenchmarkId, Criterion};
2-
use pricelevel::{Hash32, Id, OrderType, PriceLevel, Side, TimeInForce};
2+
use pricelevel::{
3+
Hash32, Id, OrderType, Price, PriceLevel, Quantity, Side, TimeInForce, TimestampMs,
4+
};
35
use std::hint::black_box;
46

57
/// Register all benchmarks for adding orders to a price level
@@ -82,11 +84,11 @@ pub fn register_benchmarks(c: &mut Criterion) {
8284
fn create_standard_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
8385
OrderType::Standard {
8486
id: Id::from_u64(id),
85-
price,
86-
quantity,
87+
price: Price::new(price),
88+
quantity: Quantity::new(quantity),
8789
side: Side::Buy,
8890
user_id: Hash32::zero(),
89-
timestamp: 1616823000000,
91+
timestamp: TimestampMs::new(1616823000000),
9092
time_in_force: TimeInForce::Gtc,
9193
extra_fields: (),
9294
}
@@ -96,12 +98,12 @@ fn create_standard_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
9698
fn create_iceberg_order(id: u64, price: u128, visible: u64, hidden: u64) -> OrderType<()> {
9799
OrderType::IcebergOrder {
98100
id: Id::from_u64(id),
99-
price,
100-
visible_quantity: visible,
101-
hidden_quantity: hidden,
101+
price: Price::new(price),
102+
visible_quantity: Quantity::new(visible),
103+
hidden_quantity: Quantity::new(hidden),
102104
side: Side::Buy,
103105
user_id: Hash32::zero(),
104-
timestamp: 1616823000000,
106+
timestamp: TimestampMs::new(1616823000000),
105107
time_in_force: TimeInForce::Gtc,
106108
extra_fields: (),
107109
}
@@ -111,11 +113,11 @@ fn create_iceberg_order(id: u64, price: u128, visible: u64, hidden: u64) -> Orde
111113
fn create_post_only_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
112114
OrderType::PostOnly {
113115
id: Id::from_u64(id),
114-
price,
115-
quantity,
116+
price: Price::new(price),
117+
quantity: Quantity::new(quantity),
116118
side: Side::Buy,
117119
user_id: Hash32::zero(),
118-
timestamp: 1616823000000,
120+
timestamp: TimestampMs::new(1616823000000),
119121
time_in_force: TimeInForce::Gtc,
120122
extra_fields: (),
121123
}
@@ -133,15 +135,15 @@ fn create_reserve_order(
133135
) -> OrderType<()> {
134136
OrderType::ReserveOrder {
135137
id: Id::from_u64(id),
136-
price,
137-
visible_quantity: visible,
138-
hidden_quantity: hidden,
138+
price: Price::new(price),
139+
visible_quantity: Quantity::new(visible),
140+
hidden_quantity: Quantity::new(hidden),
139141
side: Side::Buy,
140142
user_id: Hash32::zero(),
141-
timestamp: 1616823000000,
143+
timestamp: TimestampMs::new(1616823000000),
142144
time_in_force: TimeInForce::Gtc,
143-
replenish_threshold: threshold,
144-
replenish_amount,
145+
replenish_threshold: Quantity::new(threshold),
146+
replenish_amount: replenish_amount.map(Quantity::new),
145147
auto_replenish,
146148
extra_fields: (),
147149
}
@@ -153,11 +155,11 @@ fn create_pegged_order(id: u64, price: u128, quantity: u64) -> OrderType<()> {
153155

154156
OrderType::PeggedOrder {
155157
id: Id::from_u64(id),
156-
price,
157-
quantity,
158+
price: Price::new(price),
159+
quantity: Quantity::new(quantity),
158160
side: Side::Buy,
159161
user_id: Hash32::zero(),
160-
timestamp: 1616823000000,
162+
timestamp: TimestampMs::new(1616823000000),
161163
time_in_force: TimeInForce::Gtc,
162164
reference_price_offset: -50,
163165
reference_price_type: PegReferenceType::BestAsk,

‎benches/price_level/match_orders.rs‎

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use criterion::{BenchmarkId, Criterion};
2-
use pricelevel::{Hash32, Id, OrderType, PriceLevel, Side, TimeInForce, UuidGenerator};
2+
use pricelevel::{
3+
Hash32, Id, OrderType, Price, PriceLevel, Quantity, Side, TimeInForce, TimestampMs,
4+
UuidGenerator,
5+
};
36
use std::hint::black_box;
47
use uuid::Uuid;
58

@@ -102,11 +105,11 @@ fn setup_standard_orders(order_count: u64) -> PriceLevel {
102105
for i in 0..order_count {
103106
let order = OrderType::Standard {
104107
id: Id::from_u64(i),
105-
price: 10000u128,
106-
quantity: 10,
108+
price: Price::new(10000),
109+
quantity: Quantity::new(10),
107110
side: Side::Buy,
108111
user_id: Hash32::zero(),
109-
timestamp: 1616823000000 + i,
112+
timestamp: TimestampMs::new(1616823000000 + i),
110113
time_in_force: TimeInForce::Gtc,
111114
extra_fields: (),
112115
};
@@ -123,12 +126,12 @@ fn setup_iceberg_orders(order_count: u64) -> PriceLevel {
123126
for i in 0..order_count {
124127
let order = OrderType::IcebergOrder {
125128
id: Id::from_u64(i),
126-
price: 10000u128,
127-
visible_quantity: 5,
128-
hidden_quantity: 15,
129+
price: Price::new(10000),
130+
visible_quantity: Quantity::new(5),
131+
hidden_quantity: Quantity::new(15),
129132
side: Side::Buy,
130133
user_id: Hash32::zero(),
131-
timestamp: 1616823000000 + i,
134+
timestamp: TimestampMs::new(1616823000000 + i),
132135
time_in_force: TimeInForce::Gtc,
133136
extra_fields: (),
134137
};
@@ -145,15 +148,15 @@ fn setup_reserve_orders(order_count: u64) -> PriceLevel {
145148
for i in 0..order_count {
146149
let order = OrderType::ReserveOrder {
147150
id: Id::from_u64(i),
148-
price: 10000u128,
149-
visible_quantity: 5,
150-
hidden_quantity: 15,
151+
price: Price::new(10000),
152+
visible_quantity: Quantity::new(5),
153+
hidden_quantity: Quantity::new(15),
151154
side: Side::Buy,
152155
user_id: Hash32::zero(),
153-
timestamp: 1616823000000 + i,
156+
timestamp: TimestampMs::new(1616823000000 + i),
154157
time_in_force: TimeInForce::Gtc,
155-
replenish_threshold: 2,
156-
replenish_amount: Some(5),
158+
replenish_threshold: Quantity::new(2),
159+
replenish_amount: Some(Quantity::new(5)),
157160
auto_replenish: true,
158161
extra_fields: (),
159162
};
@@ -171,36 +174,36 @@ fn setup_mixed_orders(order_count: u64) -> PriceLevel {
171174
let order = match i % 3 {
172175
0 => OrderType::Standard {
173176
id: Id::from_u64(i),
174-
price: 10000u128,
175-
quantity: 10,
177+
price: Price::new(10000),
178+
quantity: Quantity::new(10),
176179
side: Side::Buy,
177180
user_id: Hash32::zero(),
178-
timestamp: 1616823000000 + i,
181+
timestamp: TimestampMs::new(1616823000000 + i),
179182
time_in_force: TimeInForce::Gtc,
180183
extra_fields: (),
181184
},
182185
1 => OrderType::IcebergOrder {
183186
id: Id::from_u64(i),
184-
price: 10000u128,
185-
visible_quantity: 5,
186-
hidden_quantity: 15,
187+
price: Price::new(10000),
188+
visible_quantity: Quantity::new(5),
189+
hidden_quantity: Quantity::new(15),
187190
side: Side::Buy,
188191
user_id: Hash32::zero(),
189-
timestamp: 1616823000000 + i,
192+
timestamp: TimestampMs::new(1616823000000 + i),
190193
time_in_force: TimeInForce::Gtc,
191194
extra_fields: (),
192195
},
193196
_ => OrderType::ReserveOrder {
194197
id: Id::from_u64(i),
195-
price: 10000u128,
196-
visible_quantity: 5,
197-
hidden_quantity: 15,
198+
price: Price::new(10000),
199+
visible_quantity: Quantity::new(5),
200+
hidden_quantity: Quantity::new(15),
198201
side: Side::Buy,
199202
user_id: Hash32::zero(),
200-
timestamp: 1616823000000 + i,
203+
timestamp: TimestampMs::new(1616823000000 + i),
201204
time_in_force: TimeInForce::Gtc,
202-
replenish_threshold: 2,
203-
replenish_amount: Some(5),
205+
replenish_threshold: Quantity::new(2),
206+
replenish_amount: Some(Quantity::new(5)),
204207
auto_replenish: true,
205208
extra_fields: (),
206209
},

0 commit comments

Comments
 (0)