Skip to main content

reftable_resources/
reftable_resources.rs

1//! Measures live descriptor counts around an owned reftable snapshot and compaction.
2use std::sync::atomic::AtomicBool;
3
4use girt::refs::reftable::{Snapshot, StackLimits, compact};
5use girt::refs::{Backend, Expected, RefName, Target};
6use girt::{InitKind, ObjectFormat, ObjectId, Repository};
7
8fn descriptors() -> Option<usize> {
9    #[cfg(target_os = "linux")]
10    let path = "/proc/self/fd";
11    #[cfg(target_os = "macos")]
12    let path = "/dev/fd";
13    #[cfg(any(target_os = "linux", target_os = "macos"))]
14    return std::fs::read_dir(path).ok().map(Iterator::count);
15    #[cfg(not(any(target_os = "linux", target_os = "macos")))]
16    None
17}
18
19fn main() -> Result<(), Box<dyn std::error::Error>> {
20    let root = tempfile::tempdir()?;
21    let repo = Repository::init_with_backend(
22        ObjectFormat::Sha1,
23        root.path().join("repo"),
24        InitKind::Bare,
25        Backend::Reftable,
26    )?;
27
28    let before = descriptors();
29    let refs = repo.references()?;
30    let name = RefName::new(b"refs/tags/probe")?;
31    for byte in 1..=16 {
32        refs.update_without_reflog(
33            &name,
34            Target::Direct(ObjectId::Sha1([byte; 20])),
35            Expected::Any,
36        )?;
37    }
38
39    let directory = repo.git_dir().join("reftable");
40    let snapshot = Snapshot::read(
41        &directory,
42        ObjectFormat::Sha1,
43        StackLimits::default(),
44        &AtomicBool::new(false),
45    )?;
46    let retained = descriptors();
47
48    let report = compact(
49        &directory,
50        ObjectFormat::Sha1,
51        StackLimits::default(),
52        &AtomicBool::new(false),
53    )?;
54    let after_compaction = descriptors();
55
56    assert!(report.retained.is_empty());
57    assert_eq!(snapshot.table.references.len(), 2);
58    assert!(
59        Snapshot::read(
60            &directory,
61            ObjectFormat::Sha1,
62            StackLimits::default(),
63            &AtomicBool::new(true)
64        )
65        .is_err()
66    );
67
68    drop(snapshot);
69    let after_drop = descriptors();
70    println!(
71        "descriptors before={before:?} retained={retained:?} compacted={after_compaction:?} dropped={after_drop:?}"
72    );
73    println!("compacted_tables={}", report.input_tables);
74
75    Ok(())
76}