turbo_persistence_tools/
main.rs

1#![feature(iter_intersperse)]
2
3use std::path::PathBuf;
4
5use anyhow::{Context, Result, bail};
6use turbo_persistence::{MetaFileEntryInfo, TurboPersistence};
7
8fn main() -> Result<()> {
9    // Get CLI argument
10    let path = PathBuf::from(
11        std::env::args()
12            .nth(1)
13            .context("Please provide a path to the TurboPersistence directory")?,
14    );
15    if !path.exists() {
16        bail!("The provided path does not exist: {}", path.display());
17    }
18
19    let db = TurboPersistence::open_read_only(path)?;
20    let meta_info = db
21        .meta_info()
22        .context("Failed to retrieve meta information")?;
23    for meta_file in meta_info {
24        println!(
25            "META {:08}.meta: family = {}, sst_size = {} MiB",
26            meta_file.sequence_number,
27            meta_file.family,
28            meta_file.entries.iter().map(|e| e.sst_size).sum::<u64>() / 1024 / 1024,
29        );
30        for MetaFileEntryInfo {
31            sequence_number,
32            min_hash,
33            max_hash,
34            aqmf_size,
35            aqmf_entries,
36            sst_size,
37            key_compression_dictionary_size,
38            value_compression_dictionary_size,
39            block_count,
40        } in meta_file.entries
41        {
42            println!(
43                "  SST {sequence_number:08}.sst: {min_hash:016x} - {max_hash:016x} (p = 1/{})",
44                u64::MAX / (max_hash - min_hash + 1)
45            );
46            println!("    AQMF {aqmf_entries} entries = {} KiB", aqmf_size / 1024);
47            println!(
48                "    {} KiB = {} kiB key compression dict + {} KiB value compression dict + \
49                 {block_count} blocks (avg {} bytes/block)",
50                sst_size / 1024,
51                key_compression_dictionary_size / 1024,
52                value_compression_dictionary_size / 1024,
53                (sst_size
54                    - key_compression_dictionary_size as u64
55                    - value_compression_dictionary_size as u64)
56                    / block_count as u64
57            );
58        }
59        if !meta_file.obsolete_sst_files.is_empty() {
60            println!(
61                "  OBSOLETE SSTs {}",
62                meta_file
63                    .obsolete_sst_files
64                    .iter()
65                    .map(|seq| format!("{seq:08}.sst"))
66                    .intersperse(", ".to_string())
67                    .collect::<String>()
68            );
69        }
70    }
71    Ok(())
72}