1use std::path::PathBuf;
6
7#[derive(Debug)]
9#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10#[allow(clippy::module_name_repetitions)]
11pub struct GcReport {
12 pub path: PathBuf,
14
15 pub segment_count: usize,
17
18 pub stale_segment_count: usize,
20
21 pub total_bytes: u64,
23
24 pub stale_bytes: u64,
26
27 pub total_blobs: u64,
29
30 pub stale_blobs: u64,
32}
33
34impl std::fmt::Display for GcReport {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 writeln!(f, "--- GC report for vLog @ {:?} ---", self.path)?;
37 writeln!(f, "# segments : {}", self.segment_count)?;
38 writeln!(f, "# stale : {}", self.stale_segment_count)?;
39 writeln!(f, "Total bytes: {}", self.total_bytes)?;
40 writeln!(f, "Stale bytes: {}", self.stale_bytes)?;
41 writeln!(f, "Total blobs: {}", self.total_blobs)?;
42 writeln!(f, "Stale blobs: {}", self.stale_blobs)?;
43 writeln!(f, "Stale ratio: {}", self.stale_ratio())?;
44 writeln!(f, "Space amp : {}", self.space_amp())?;
45 writeln!(f, "--- GC report done ---")?;
46 Ok(())
47 }
48}
49
50impl GcReport {
51 #[must_use]
53 pub fn space_amp(&self) -> f32 {
54 if self.total_bytes == 0 {
55 return 0.0;
56 }
57
58 let alive_bytes = self.total_bytes - self.stale_bytes;
59 if alive_bytes == 0 {
60 return 0.0;
61 }
62
63 self.total_bytes as f32 / alive_bytes as f32
64 }
65
66 #[must_use]
68 pub fn stale_ratio(&self) -> f32 {
69 if self.total_bytes == 0 {
70 return 0.0;
71 }
72
73 if self.stale_bytes == 0 {
74 return 0.0;
75 }
76
77 self.stale_bytes as f32 / self.total_bytes as f32
78 }
79}