#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::arithmetic_side_effects,
clippy::indexing_slicing
)]
use doubleentry::period::LedgerId;
use doubleentry::{
Amount, BalanceKey, BalanceQuery, Currency, Entry, EntryId, IdempotencyKey, Journal, Layer,
};
use time::macros::date;
type Eur = Amount<2>;
fn append_cost(accounts: usize, entries: usize) -> std::time::Duration {
let mut journal = Journal::<2>::new(LedgerId::new("scale").unwrap());
let ids: Vec<_> = (0..accounts)
.map(|i| {
journal
.register_path(&format!("A:{i:06}"), date!(2020 - 01 - 01))
.unwrap()
})
.collect();
for i in 0..accounts - 1 {
journal
.record(
Entry::new(
EntryId::generate(),
IdempotencyKey::new(format!("seed{i}").into_bytes()).unwrap(),
date!(2026 - 03 - 15),
)
.debit(ids[i], Eur::from_minor(1), Currency::EUR)
.credit(ids[i + 1], Eur::from_minor(1), Currency::EUR),
)
.unwrap();
}
let start = std::time::Instant::now();
for i in 0..entries {
journal
.record(
Entry::new(
EntryId::generate(),
IdempotencyKey::new(format!("k{i}").into_bytes()).unwrap(),
date!(2026 - 03 - 15),
)
.debit(ids[0], Eur::from_minor(100), Currency::EUR)
.credit(ids[1], Eur::from_minor(100), Currency::EUR),
)
.unwrap();
}
let elapsed = start.elapsed();
let key = BalanceKey {
account: ids[0],
currency: Currency::EUR,
layer: Layer::Settled,
};
assert_eq!(
journal.balance(&key, BalanceQuery::all()).unwrap().debits,
Eur::from_minor(100 * entries as i64 + 1)
);
assert_eq!(
journal.statement(&key, BalanceQuery::all()).unwrap().len(),
entries + 1
);
elapsed
}
fn ratio(a: std::time::Duration, b: std::time::Duration) -> f64 {
b.as_secs_f64() / a.as_secs_f64().max(1e-6)
}
#[test]
fn appending_does_not_get_quadratically_slower() {
let small = append_cost(2, 2_000);
let large = append_cost(2, 8_000);
let r = ratio(small, large);
assert!(
r < 9.0,
"appending 4x the entries took {r:.1}x the time ({small:?} -> {large:?})"
);
}
#[test]
fn appending_does_not_get_slower_as_the_chart_of_accounts_grows() {
let narrow = append_cost(50, 2_000);
let wide = append_cost(5_000, 2_000);
let r = ratio(narrow, wide);
assert!(
r < 4.0,
"100x the accounts made an append {r:.1}x more expensive ({narrow:?} -> {wide:?})"
);
}