Skip to content

Commit

Permalink
feat: add new order in trade msg (#189)
Browse files Browse the repository at this point in the history
* feat: add order in trade msg

* feat: add global string intern pool

* fix

* lint
  • Loading branch information
lispc authored Jun 20, 2021
1 parent 0f8cc5f commit 7570f31
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 19 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ futures-util = { version = "0.3.13", default-features = false }
humantime-serde = "1.0.1"
hyper = "0.14.4"
itertools = "0.10.0"
lazy_static = "1.4.0"
log = "0.4.14"
nix = "0.20.0"
num_enum = "0.5.1"
Expand Down
11 changes: 10 additions & 1 deletion src/matchengine/market/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ impl Market {
bid_order_id: bid_order.id,
bid_role: if taker_is_ask { MarketRole::MAKER } else { MarketRole::TAKER },
bid_fee,

ask_order: None,
bid_order: None,
#[cfg(feature = "emit_state_diff")]
state_before: Default::default(),
#[cfg(feature = "emit_state_diff")]
Expand All @@ -355,6 +358,10 @@ impl Market {
if self.disable_self_trade {
debug_assert_ne!(trade.ask_user_id, trade.bid_user_id);
}
let ask_order_is_new = ask_order.finished_base.is_zero();
let ask_order_before = *ask_order;
let bid_order_is_new = bid_order.finished_base.is_zero();
let bid_order_before = *bid_order;
ask_order.remain -= traded_base_amount;
bid_order.remain -= traded_base_amount;
ask_order.finished_base += traded_base_amount;
Expand Down Expand Up @@ -412,6 +419,8 @@ impl Market {
state_after,
#[cfg(feature = "emit_state_diff")]
state_before,
ask_order: if ask_order_is_new { Some(ask_order_before) } else { None },
bid_order: if bid_order_is_new { Some(bid_order_before) } else { None },
..trade
};
persistor.put_trade(&trade);
Expand All @@ -420,7 +429,7 @@ impl Market {

let maker_finished = maker.remain.is_zero();
if maker_finished {
finished_orders.push(maker.clone());
finished_orders.push(*maker);
} else {
// When maker_finished, `order_finish` will send message.
// So we don't need to send the finish message here.
Expand Down
26 changes: 9 additions & 17 deletions src/matchengine/market/order.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::types::{OrderSide, OrderType};
use crate::utils::intern_string;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
Expand Down Expand Up @@ -73,45 +74,36 @@ impl PartialOrd for MarketKeyBid {
}
}

#[derive(Debug, Clone)]
pub enum MarketString {
Left(&'static str),
Right(String),
}
#[derive(Debug, Clone, Copy)]
pub struct MarketString(&'static str);

impl From<&'static str> for MarketString {
fn from(str: &'static str) -> Self {
MarketString::Left(str)
MarketString(str)
}
}

impl std::ops::Deref for MarketString {
type Target = str;
fn deref(&self) -> &Self::Target {
match self {
MarketString::Left(str) => *str,
MarketString::Right(stri) => stri.as_str(),
}
self.0
}
}

impl serde::ser::Serialize for MarketString {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self {
MarketString::Left(str) => serializer.serialize_str(*str),
MarketString::Right(stri) => serializer.serialize_str(stri.as_str()),
}
serializer.serialize_str(self.0)
}
}

impl<'de> serde::de::Deserialize<'de> for MarketString {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
Ok(MarketString::Right(s))
Ok(intern_string(&s).into())
}
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct Order {
pub id: u64,
pub base: MarketString,
Expand Down Expand Up @@ -181,6 +173,6 @@ impl OrderRc {
}

pub(super) fn deep(&self) -> Order {
self.borrow().clone()
*self.borrow()
}
}
5 changes: 5 additions & 0 deletions src/matchengine/market/trade.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::market::Order;
use crate::types::MarketRole;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -47,6 +48,10 @@ pub struct Trade {
pub bid_role: MarketRole,
pub bid_fee: Decimal,

// only not none when this is this order's first trade
pub ask_order: Option<Order>,
pub bid_order: Option<Order>,

#[cfg(feature = "emit_state_diff")]
pub state_before: VerboseTradeState,
#[cfg(feature = "emit_state_diff")]
Expand Down
13 changes: 13 additions & 0 deletions src/matchengine/sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pub struct Sequencer {
order_id: u64,
trade_id: u64,
msg_id: u64,
operation_log_id: u64,
}

Expand All @@ -10,6 +11,7 @@ impl Sequencer {
self.set_operation_log_id(0);
self.set_order_id(0);
self.set_trade_id(0);
self.set_msg_id(0);
}
pub fn next_order_id(&mut self) -> u64 {
self.order_id += 1;
Expand All @@ -24,6 +26,10 @@ impl Sequencer {
self.operation_log_id += 1;
self.operation_log_id
}
pub fn next_msg_id(&mut self) -> u64 {
self.msg_id += 1;
self.msg_id
}
pub fn get_operation_log_id(&self) -> u64 {
self.operation_log_id
}
Expand All @@ -33,6 +39,9 @@ impl Sequencer {
pub fn get_order_id(&self) -> u64 {
self.order_id
}
pub fn get_msg_id(&self) -> u64 {
self.msg_id
}
pub fn set_operation_log_id(&mut self, id: u64) {
log::debug!("set operation_log id {}", id);
self.operation_log_id = id;
Expand All @@ -45,4 +54,8 @@ impl Sequencer {
log::debug!("set order id {}", id);
self.order_id = id;
}
pub fn set_msg_id(&mut self, id: u64) {
log::debug!("set msg id {}", id);
self.msg_id = id;
}
}
2 changes: 1 addition & 1 deletion src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl OrderMessage {
pub fn from_order(order: &Order, at_step: OrderEventType) -> Self {
Self {
event: at_step,
order: order.clone(),
order: *order,
base: order.base.to_string(),
quote: order.quote.to_string(),
}
Expand Down
2 changes: 2 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
pub mod timeutil;
pub use timeutil::*;
pub mod strings;
pub use strings::*;
14 changes: 14 additions & 0 deletions src/utils/strings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::sync::Mutex;
lazy_static! {
pub static ref STRING_POOL: Mutex<HashMap<String, &'static str>> = Default::default();
}

pub fn intern_string(s: &str) -> &'static str {
*STRING_POOL
.lock()
.unwrap()
.entry(s.to_owned())
.or_insert_with(|| Box::leak(s.to_string().into_boxed_str()))
}

0 comments on commit 7570f31

Please sign in to comment.