use feltdb::FeltDb;
use serde::{Deserialize, Serialize};
use std::time::Instant;
#[derive(Serialize, Deserialize, Clone)]
struct Item {
n: u64,
active: bool,
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
for size in [1_000u64, 10_000, 100_000] {
let directory = std::env::temp_dir().join(format!("feltdb-subscription-cost-{size}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&directory);
std::fs::create_dir_all(&directory).unwrap();
let db = FeltDb::open(directory.join("state.log")).unwrap();
for n in 0..size {
db.insert(&format!("items:{n}"), Item { n, active: n % 10 == 0 }).unwrap();
}
let subscribers = 10;
let mut live = Vec::new();
for _ in 0..subscribers {
live.push(db.capability("items").live_find::<Item, _>(|item| item.active).await.unwrap());
}
let began = Instant::now();
let _probe = db.capability("items").live_find::<Item, _>(|item| item.active).await.unwrap();
let rescan_ms = began.elapsed().as_secs_f64() * 1000.0;
let writes = 200;
let began = Instant::now();
for w in 0..writes {
db.insert(&format!("items:new{w}"), Item { n: size + w, active: true }).unwrap();
for subscription in &mut live {
subscription.next().await.unwrap();
}
}
let per_change_ms = began.elapsed().as_secs_f64() * 1000.0 / writes as f64;
println!(
"{{\"size\":{size},\"subscribers\":{subscribers},\"matches\":{},\"change_all_subscribers_ms\":{per_change_ms:.3},\"rescan_one_subscription_ms\":{rescan_ms:.3}}}",
size / 10 + writes
);
drop(live);
drop(db);
let _ = std::fs::remove_dir_all(&directory);
}
}