1use std::process::Command;
11
12use chrono::Local;
13use tokenburn_core::{
14 build_report, by_project, collect, drill, pie, time_series, Query, Selection, ToolFilter,
15 Window,
16};
17
18fn rss_mb() -> f64 {
19 let out = Command::new("ps")
20 .args(["-o", "rss=", "-p", &std::process::id().to_string()])
21 .output()
22 .expect("ps");
23 String::from_utf8_lossy(&out.stdout)
24 .trim()
25 .parse::<f64>()
26 .unwrap_or(0.0)
27 / 1024.0
28}
29
30fn main() {
31 let mut args = std::env::args().skip(1);
32 let rounds: usize = args.next().and_then(|n| n.parse().ok()).unwrap_or(100);
33 let window = match args.next().as_deref() {
34 Some("all") => Window::All,
35 _ => Window::Month,
36 };
37 let query = Query {
38 bucket: tokenburn_core::Bucket::Day,
39 window,
40 ..Query::default()
41 };
42
43 println!("round rows rss MB");
44 let mut first = 0.0;
45 for i in 0..rounds {
46 let collected = collect(ToolFilter::All, window.start(Local::now()));
47 let rows = collected.rows;
48 let _ = build_report(&rows, &query);
49 let _ = time_series(&rows, &query);
50 let _ = pie(&by_project(&rows), 8);
51 let all = drill(&rows, &query, &Selection::default());
52 let mut sel = Selection::default();
54 if let Some(l) = all.series.labels.get(3) {
55 sel.toggle_bucket(l);
56 }
57 if let Some(k) = all.pie.slices.first().and_then(|s| s.key.clone()) {
58 sel.toggle_project(&k);
59 }
60 let _ = drill(&rows, &query, &sel);
61 if i == 0 || i % (rounds / 10).max(1) == 0 || i == rounds - 1 {
62 let rss = rss_mb();
63 if i == 0 {
64 first = rss;
65 }
66 println!("{i:>5} {:>6} {rss:>7.1}", rows.len());
67 }
68 }
69 println!("first round {first:.1} MB → last round {:.1} MB", rss_mb());
70}