value_log/gc/
report.rs

1// Copyright (c) 2024-present, fjall-rs
2// This source code is licensed under both the Apache 2.0 and MIT License
3// (found in the LICENSE-* files in the repository)
4
5use std::path::PathBuf;
6
7/// Statistics report for garbage collection
8#[derive(Debug)]
9#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10#[allow(clippy::module_name_repetitions)]
11pub struct GcReport {
12    /// Path of value log
13    pub path: PathBuf,
14
15    /// Segment count
16    pub segment_count: usize,
17
18    /// Segments that have 100% stale blobs
19    pub stale_segment_count: usize,
20
21    /// Amount of stored bytes
22    pub total_bytes: u64,
23
24    /// Amount of bytes that could be freed
25    pub stale_bytes: u64,
26
27    /// Amount of stored blobs
28    pub total_blobs: u64,
29
30    /// Amount of blobs that could be freed
31    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    /// Calculates the space amplification factor.
52    #[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    /// Calculates the stale ratio (percentage).
67    #[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}