reftable_resources/
reftable_resources.rs1use 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}