use crate::{
data::order::BookOrder,
enums::{BookType, RecordFlag},
};
#[inline]
fn price_to_order_id(price_raw: i128) -> u64 {
let build_hasher = ahash::RandomState::with_seeds(0, 0, 0, 0);
build_hasher.hash_one(price_raw)
}
#[inline]
fn price_based_order_id(order: &BookOrder) -> u64 {
#[cfg(feature = "high-precision")]
{
price_to_order_id(order.price.raw)
}
#[cfg(not(feature = "high-precision"))]
{
price_to_order_id(order.price.raw as i128)
}
}
pub(crate) fn pre_process_order(book_type: BookType, mut order: BookOrder, flags: u8) -> BookOrder {
match book_type {
BookType::L1_MBP => order.order_id = order.side as u64,
BookType::L2_MBP => order.order_id = price_based_order_id(&order),
BookType::L3_MBO => {
if RecordFlag::F_TOB.matches(flags) {
order.order_id = order.side as u64;
} else if RecordFlag::F_MBP.matches(flags) {
order.order_id = price_based_order_id(&order);
}
}
}
order
}
#[cfg(test)]
mod tests {
use std::sync::{LazyLock, Mutex};
use ahash::AHashSet;
use nautilus_core::MUTEX_POISONED;
use rstest::rstest;
use super::*;
#[rstest]
fn test_price_to_order_id_deterministic() {
let price1 = 123456789012345678901234567890_i128;
let price2 = 987654321098765432109876543210_i128;
let id1_a = price_to_order_id(price1);
let id1_b = price_to_order_id(price1);
assert_eq!(id1_a, id1_b, "Same price must produce same order_id");
let id2 = price_to_order_id(price2);
assert_ne!(
id1_a, id2,
"Different prices should produce different order_ids"
);
for _ in 0..100 {
assert_eq!(price_to_order_id(price1), id1_a);
assert_eq!(price_to_order_id(price2), id2);
}
}
#[rstest]
fn test_price_to_order_id_no_collisions() {
let base = 1000000000_i128;
let mut seen = AHashSet::new();
for i in 0..1000 {
let price = base + i;
let id = price_to_order_id(price);
assert!(seen.insert(id), "Collision detected for price {price}");
}
}
#[rstest]
fn test_price_to_order_id_no_collision_across_64bit_boundary() {
let price1 = 1_i128;
let price2 = 1_i128 << 64;
let id1 = price_to_order_id(price1);
let id2 = price_to_order_id(price2);
assert_ne!(
id1, id2,
"Collision detected: price 1 and price 2^64 must have different order_ids"
);
}
#[rstest]
fn test_price_to_order_id_handles_negative_prices() {
let mut seen = AHashSet::new();
let negative_prices = vec![
-1_i128,
-2_i128,
-100_i128,
-1000000000_i128,
i128::MIN,
i128::MIN + 1,
];
for &price in &negative_prices {
let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for negative price {price}"
);
}
let positive_prices = vec![1_i128, 2_i128, 100_i128, 1000000000_i128, i128::MAX];
for &price in &positive_prices {
let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected between negative and positive price: {price}"
);
}
}
#[rstest]
fn test_price_to_order_id_handles_large_values() {
let mut seen = AHashSet::new();
let large_values = vec![
u64::MAX as i128, 1_i128 << 64, (u64::MAX as i128) + 1000,
1_i128 << 65, 1_i128 << 100, i128::MAX - 1,
i128::MAX,
];
for &price in &large_values {
let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for large price value {price}"
);
}
}
#[rstest]
fn test_price_to_order_id_multiples_of_2_pow_64() {
let mut seen = AHashSet::new();
for i in 0..10 {
let price = i * (1_i128 << 64);
let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for price {price} (multiple of 2^64)"
);
}
}
#[rstest]
fn test_price_to_order_id_realistic_orderbook_prices() {
let mut seen = AHashSet::new();
let btc_base = 50000_000000000_i128;
for i in -1000..1000 {
let price = btc_base + i; let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for BTC price offset {i}"
);
}
let forex_base = 1_100000000_i128;
for i in -10000..10000 {
let price = forex_base + i; let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for EURUSD price offset {i}"
);
}
let doge_base = 100000000_i128; for i in -100000..100000 {
let price = doge_base + i;
let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for DOGE price offset {i}"
);
}
}
#[rstest]
fn test_price_to_order_id_edge_case_patterns() {
let mut seen = AHashSet::new();
for power in 0..128 {
let price = 1_i128 << power;
let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for 2^{power} = {price}"
);
}
for power in 0..127 {
let price = -(1_i128 << power);
let id = price_to_order_id(price);
assert!(
seen.insert(id),
"Collision detected for -2^{power} = {price}"
);
}
}
#[rstest]
fn test_price_to_order_id_sequential_negative_values() {
let mut seen = AHashSet::new();
for i in -10000..=0 {
let price = i as i128;
let id = price_to_order_id(price);
assert!(seen.insert(id), "Collision detected for price {i}");
}
}
#[rstest]
#[case::max(i128::MAX)]
#[case::max_minus_1(i128::MAX - 1)]
#[case::min(i128::MIN)]
#[case::min_plus_1(i128::MIN + 1)]
#[case::u64_max(u64::MAX as i128)]
#[case::u64_max_minus_1((u64::MAX as i128) - 1)]
#[case::u64_max_plus_1((u64::MAX as i128) + 1)]
#[case::neg_u64_max(-(u64::MAX as i128))]
#[case::neg_u64_max_minus_1(-(u64::MAX as i128) - 1)]
#[case::neg_u64_max_plus_1(-(u64::MAX as i128) + 1)]
#[case::zero(0_i128)]
#[case::one(1_i128)]
#[case::neg_one(-1_i128)]
fn test_price_to_order_id_extreme_values_no_collision(#[case] price: i128) {
static SEEN: LazyLock<Mutex<AHashSet<u64>>> = LazyLock::new(|| Mutex::new(AHashSet::new()));
let id = price_to_order_id(price);
let mut seen = SEEN.lock().expect(MUTEX_POISONED);
assert!(
seen.insert(id),
"Collision detected for extreme value: {price} (order_id: {id})"
);
}
#[rstest]
fn test_price_to_order_id_avalanche_effect() {
let base_price = 1000000000000_i128;
let id1 = price_to_order_id(base_price);
let id2 = price_to_order_id(base_price + 1);
let xor = id1 ^ id2;
let differing_bits = xor.count_ones();
assert!(
differing_bits >= 12,
"Poor avalanche: only {differing_bits}/64 bits differ for adjacent prices"
);
}
#[rstest]
fn test_price_to_order_id_comprehensive_collision_check() {
const TOTAL_TESTS: usize = 500_000;
let mut seen = AHashSet::new();
let mut collision_count = 0;
for i in -100_000..100_000 {
let id = price_to_order_id(i as i128);
if !seen.insert(id) {
collision_count += 1;
}
}
for power in 0..64 {
for offset in -10..=10 {
let price = (1_i128 << power) + offset;
let id = price_to_order_id(price);
if !seen.insert(id) {
collision_count += 1;
}
}
}
for base in [100, 1000, 10000, 100000, 1000000, 10000000] {
for i in 0..1000 {
let price = base * 1_000_000_000_i128 + i;
let id = price_to_order_id(price);
if !seen.insert(id) {
collision_count += 1;
}
}
}
let collision_rate = collision_count as f64 / TOTAL_TESTS as f64;
assert!(
collision_rate < 0.001,
"High collision rate: {collision_rate:.6}% ({collision_count}/{TOTAL_TESTS})"
);
println!(
"✓ Tested {} unique prices, {} collisions ({:.6}%)",
TOTAL_TESTS,
collision_count,
collision_rate * 100.0
);
}
}