This repository has no description
2.0 kB
62 lines
1//! Counters written to OUT/stats.json (and merged into closure.json).
2
3use std::collections::BTreeMap;
4use std::path::PathBuf;
5use std::sync::Mutex;
6
7#[derive(Default)]
8struct Inner {
9 c: BTreeMap<String, u64>,
10 nars: Vec<(String, u64, u64)>,
11}
12
13#[derive(Default)]
14pub struct Stats {
15 path: Option<PathBuf>,
16 inner: Mutex<Inner>,
17}
18
19impl Stats {
20 pub fn new(path: Option<PathBuf>) -> Stats {
21 Stats {
22 path,
23 ..Default::default()
24 }
25 }
26
27 pub fn add(&self, kind: &str, nbytes: u64) {
28 let mut i = self.inner.lock().unwrap();
29 *i.c.entry(format!("{kind}_count")).or_default() += 1;
30 *i.c.entry(format!("{kind}_bytes")).or_default() += nbytes;
31 }
32
33 pub fn nar(&self, name: &str, file_bytes: u64, nar_bytes: u64) {
34 {
35 let mut i = self.inner.lock().unwrap();
36 i.nars.push((name.to_string(), file_bytes, nar_bytes));
37 *i.c.entry("nar_count".into()).or_default() += 1;
38 *i.c.entry("nar_bytes".into()).or_default() += file_bytes;
39 *i.c.entry("nar_unpacked_bytes".into()).or_default() += nar_bytes;
40 }
41 self.save();
42 }
43
44 pub fn counters(&self) -> serde_json::Map<String, serde_json::Value> {
45 let i = self.inner.lock().unwrap();
46 i.c.iter().map(|(k, v)| (k.clone(), (*v).into())).collect()
47 }
48
49 pub fn save(&self) {
50 let Some(path) = &self.path else { return };
51 let i = self.inner.lock().unwrap();
52 let mut j: serde_json::Map<_, _> =
53 i.c.iter().map(|(k, v)| (k.clone(), (*v).into())).collect();
54 j.insert("nars".into(), serde_json::to_value(&i.nars).unwrap());
55 let tmp = path.with_extension("json.tmp");
56 let r = std::fs::write(&tmp, serde_json::to_vec(&j).unwrap())
57 .and_then(|_| std::fs::rename(&tmp, path));
58 if let Err(e) = r {
59 eprintln!("writing {}: {e}", path.display());
60 }
61 }
62}