Skip to content

feat: add bdstorage status subcommand — passive vault inspection without filesystem re-scan#63

Merged
Rakshat28 merged 10 commits into
Rakshat28:mainfrom
Itzzavdheshh:storage
May 19, 2026
Merged

feat: add bdstorage status subcommand — passive vault inspection without filesystem re-scan#63
Rakshat28 merged 10 commits into
Rakshat28:mainfrom
Itzzavdheshh:storage

Conversation

@Itzzavdheshh

Copy link
Copy Markdown
Contributor

#Program
NSOC & GSSOC


feat: bdstorage status Subcommand — Passive Vault Summary & JSON Output

Closes #43


What This PR Does

Adds a new bdstorage status subcommand that retrieves all vault metrics directly from the existing redb database — zero filesystem re-scan, zero I/O overhead. Users can now instantly answer "how much space has been saved so far?" without triggering an expensive scan or dedupe run.

All existing subcommands are 100% unchanged. status is purely additive.

Core output introduced:

Vault location    : ~/.imprint/store/
Objects in vault  : 1 234
Total vault size  : 4.7 GB
Tracked paths     : 3 891
Estimated savings : 11.2 GB
Deduplication ratio: 3.38×

JSON mode (--json flag):

{
  "vault_location": "~/.imprint/store/",
  "objects_in_vault": 1234,
  "total_vault_size": 4928937164,
  "tracked_paths": 3891,
  "estimated_savings": 12025757286,
  "deduplication_ratio": 3.38
}

Problem

  • No way to inspect vault state without triggering a full filesystem re-scan via scan or dedupe
  • "How much space has been saved?" required expensive I/O — unusable in monitoring scripts or dashboards
  • The redb database (~/.imprint/state.redb) already tracked all required metrics — but had no read API
  • No machine-readable output path for the vault state — impossible to use in CI or automation
  • No clear user-facing error when status is called before any vault has been created

Solution

A status subcommand reading exclusively from FILE_INDEX and CAS_INDEX redb tables. A VaultSummary struct with full serde support. Human-readable formatted output using the existing colored crate. A --json flag for machine-readable output. A clear early-exit error when no vault exists. Unit tests for summary computation logic. Integration tests for both text and JSON modes.


Changes — Deep Dive


1. src/state.rsVaultSummary Struct + compute_summary()

New VaultSummary struct:

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
pub struct VaultSummary {
    pub vault_location: String,
    pub objects_in_vault: usize,
    pub total_vault_size: u64,
    pub tracked_paths: usize,
    pub estimated_savings: u64,
    pub deduplication_ratio: f64,
}
  • serde::Serialize + serde::Deserialize derived — ready for --json output and testing
  • PartialEq derived — enables direct equality assertions in unit tests

compute_summary() implementation:

pub fn compute_summary(&self, vault_location: &Path) -> Result<VaultSummary>
  • Returns clear error immediately if vault path does not exist — no silent failure
  • Opens FILE_INDEX read-only — single pass builds HashMap<hash → size>
  • Opens CAS_INDEX — filters for entries with refcount > 0 that physically exist on disk in the sharded vault
  • Tracked paths — total entry count in FILE_INDEX
  • Objects in vaultCAS_INDEX entries with refcount > 0 confirmed present on disk
  • Total vault size — sum of physical sizes of all confirmed vault objects
  • Estimated savingssize × (refcount - 1) for every vaulted hash
  • Deduplication ratio(total_vault_size + estimated_savings) / total_vault_size; defaults to 1.0 when total_vault_size == 0
  • redb::ReadableTable imported — enables read-only iteration over tables

New unit tests:

  • test_compute_summary — populates mock state DB with duplicate and unique entries; asserts savings and deduplication ratio match expected values
  • test_compute_summary_ignores_missing_vault_objects — validates that index entries without corresponding physical vault files are excluded from all metrics

2. src/main.rsStatus Subcommand Registration + Execution

Commands enum — new variant:

Status {
    #[arg(long, action = clap::ArgAction::SetTrue)]
    json: bool,
}
  • --json is a local flag scoped to status only — does not affect dedupe or scan
  • Registered via clap — appears correctly in bdstorage --help and bdstorage status --help

Execution in run():

  • Early exit with clear error if ~/.imprint/state.redb does not exist:
    [ERROR] No vault found. Run 'bdstorage dedupe <path>' first to create the vault.
    
  • Opens database in read-only mode via open_readonly_if_exists() — zero write risk
  • Calls compute_summary() → formats output based on --json flag

Formatting helpers added:

  • format_number(val: usize) — space-delimited thousands (e.g. 1 234, 3 891)
  • format_bytes(bytes: u64) — human-readable with one decimal place (KB, MB, GB, TB)
  • print_vault_status(summary: &VaultSummary) — neatly aligned output using colored crate; replaces absolute home directory path with ~ shortcut; formats ratio with × character

3. tests/integration_tests.rs — Two New Integration Tests

test_status_command:

  • Asserts bdstorage status exits with failure code on uninitialized environment
  • Runs dedupe to initialize the vault
  • Asserts bdstorage status (text mode) prints all required fields: vault location, objects, vault size, tracked paths, savings, ratio
  • Asserts bdstorage status --json produces valid, parseable JSON with correct structural fields and accurate values

test_status_after_scan_without_vault_fails:

  • Confirms that running scan (without dedupe) then calling status exits cleanly with the "no vault found" error — not a panic, not a crash

Files Changed

File Action Notes
src/state.rs Modified VaultSummary struct, compute_summary(), ReadableTable import, 2 unit tests
src/main.rs Modified Status variant, run() wiring, 3 formatting helpers
tests/integration_tests.rs Modified 2 new integration tests — text mode + JSON mode + scan-without-dedupe guard

Error Handling

  • bdstorage status with no vault exits with non-zero code and clear message
  • bdstorage status after scan (no dedupe) exits with non-zero code and clear message
  • No panic, no cryptic redb error — always a human-readable failure

Testing

  • state::tests::test_compute_summaryok
  • state::tests::test_compute_summary_ignores_missing_vault_objectsok
  • test_status_commandok
  • test_status_after_scan_without_vault_failsok
  • cargo fmt --all -- --checkPass
  • cargo clippy --all-targets --all-features -- -D warningsPass
  • cargo test — all tests pass

No Regression

  • bdstorage scan output and behaviour unchanged
  • bdstorage dedupe output and behaviour unchanged
  • Database opened read-only in status — zero write risk to existing vault state

🧪 How to Test

# Build
cargo build --release

# Formatter
cargo fmt --all -- --check

# Linter
cargo clippy --all-targets --all-features -- -D warnings

# Full test suite
cargo test

# Manual — status before any vault exists
./target/release/bdstorage status
# Expected: [ERROR] No vault found. Run 'bdstorage dedupe <path>' first

# Manual — initialize vault then check status
./target/release/bdstorage dedupe /path/to/test/dir
./target/release/bdstorage status

# Manual — JSON output
./target/release/bdstorage status --json
./target/release/bdstorage status --json | jq .estimated_savings
./target/release/bdstorage status --json | jq .deduplication_ratio

Test Checklist — Text Mode

  • Run bdstorage status before any dedupe → verify clean error message, non-zero exit
  • Run bdstorage scan /path then bdstorage status (no dedupe) → verify clean error, non-zero exit
  • Run bdstorage dedupe /path → run bdstorage status → verify all 6 fields present
  • Verify numbers use space-delimited thousands (1 234 not 1234)
  • Verify byte sizes are human-readable (4.7 GB not 5049942220)
  • Verify ratio shows × character (3.38×)
  • Verify vault path shows ~ not absolute home directory

Test Checklist — JSON Mode

  • Run bdstorage status --json → pipe to jq . → verify valid formatted JSON
  • Run bdstorage status --json | jq .objects_in_vault → verify numeric value returned
  • Run bdstorage status --json | jq .deduplication_ratio → verify float value returned
  • Run bdstorage status --json | jq .estimated_savings → verify numeric value returned
  • Run bdstorage status --json before vault exists → verify non-zero exit, error to stderr, no JSON on stdout

Test Checklist — Metric Accuracy

  • Create fixture: 3 identical 100MB files + 1 unique 50MB file → run dedupe
  • Run bdstorage status → verify objects_in_vault = 2 (1 deduped + 1 unique)
  • Verify estimated_savings ≈ 200MB (2 redundant copies of the 100MB file)
  • Verify tracked_paths = 4
  • Manually delete a vault object file → run bdstorage status → verify it is excluded from counts

Test Checklist — No Regression

  • Run bdstorage dedupe /path → output identical to pre-PR
  • Run bdstorage scan /path → output identical to pre-PR
  • Run cargo test → all pre-existing tests still pass

Screenshots


1. bdstorage status — text mode, full formatted output
image



2. bdstorage status --json — raw JSON output
image



3. bdstorage status --json | jq .estimated_savings — piped to jq
image



4. bdstorage status before vault exists — clear error message
image



5. bdstorage status after scan but before dedupe — clean failure
image



6. cargo test — all tests passing including new unit + integration tests
image



7. cargo clippy — zero warnings
image



8. Metric accuracy — estimated_savings and deduplication_ratio verified against known fixture
image


✅ Checklist

  • I am contributing under NSOC & GSSOC
  • My code follows the project's existing style
  • I have tested my changes locally via cargo test
  • I have linked the related issue above
  • My PR title follows Conventional Commits format — feat: add bdstorage status subcommand — passive vault inspection without filesystem re-scan
  • bdstorage status reads DB only — zero filesystem re-scan triggered
  • bdstorage status --json produces valid JSON parseable by jq
  • Clear error message shown when no vault exists — no panic, no cryptic redb error
  • scan without dedupe followed by status exits cleanly with descriptive error
  • VaultSummary struct derives Serialize, Deserialize, and PartialEq
  • Database opened strictly read-only — vault state cannot be corrupted by status
  • test_compute_summary unit test passes — ok
  • test_compute_summary_ignores_missing_vault_objects unit test passes — ok
  • test_status_command integration test passes — ok
  • test_status_after_scan_without_vault_fails integration test passes — ok
  • cargo fmt --all -- --checkPass
  • cargo clippy --all-targets --all-features -- -D warningsPass
  • Existing scan and dedupe subcommands fully unaffected — zero regression
  • No unsafe blocks introduced

Contribution Note

Hi @Rakshat28

This PR delivers the complete bdstorage status subcommand as described in the issue — every acceptance criterion met, every edge case handled, and all CI checks passing.

  • Zero re-scanstatus reads exclusively from FILE_INDEX and CAS_INDEX redb tables; the filesystem is never walked
  • All 6 fields present — vault location (~ shortcut), objects in vault, total vault size, tracked paths, estimated savings, deduplication ratio with ×
  • --json flagVaultSummary fully serialised via serde_json; pipes cleanly to jq
  • Clear error handling — no vault → clean message + non-zero exit; scan without dedupe → same; no panics, no cryptic redb errors
  • VaultSummary structSerialize + Deserialize + PartialEq derived; used in both output and test assertions
  • 4 tests added — 2 unit tests in state.rs (summary computation + missing vault object exclusion), 2 integration tests (text+JSON mode, scan-without-dedupe guard)
  • cargo fmt, cargo clippy, cargo test — all three CI gates pass clean
  • Only 3 files changed — surgical, zero disruption to existing scan and dedupe paths

Happy to address any feedback or adjustments based on your review! 🚀


Labels

#feature #cli #rust #redb #vault #status-command #json-output #serde #unit-tests #integration-tests #performance #NSoC26 #nsoc #GSSOC


Submitted as part of Open Source Contribution — NSoC (Nexus Spring of Code) & GSSoC

@Itzzavdheshh

Itzzavdheshh commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

Hi @Rakshat28

This PR delivers the complete bdstorage status subcommand as described in the issue — every acceptance criterion met, every edge case handled, and all CI checks passing.

  • Zero re-scanstatus reads exclusively from FILE_INDEX and CAS_INDEX redb tables; the filesystem is never walked
  • All 6 fields present — vault location (~ shortcut), objects in vault, total vault size, tracked paths, estimated savings, deduplication ratio with ×
  • --json flagVaultSummary fully serialised via serde_json; pipes cleanly to jq
  • Clear error handling — no vault → clean message + non-zero exit; scan without dedupe → same; no panics, no cryptic redb errors
  • VaultSummary structSerialize + Deserialize + PartialEq derived; used in both output and test assertions
  • 4 tests added — 2 unit tests in state.rs (summary computation + missing vault object exclusion), 2 integration tests (text+JSON mode, scan-without-dedupe guard)
  • cargo fmt, cargo clippy, cargo test — all three CI gates pass clean
  • Only 3 files changed — surgical, zero disruption to existing scan and dedupe paths

Happy to address any feedback or adjustments based on your review! 🚀

@Rakshat28

Rakshat28 commented May 19, 2026

Copy link
Copy Markdown
Owner

@Itzzavdheshh Please resolve merge conflict(s) and make sure feature added by last merged PR(which plays with the option of changing default vault location) is also integrated with this.
Also make apt changes in README.md for subcommand.

@Itzzavdheshh

Copy link
Copy Markdown
Contributor Author

Hello @Rakshat28, I have made the requested changes. Please confirm whether everything is now updated according to your suggestions. Also, it would be a big help if you could add the appropriate type labels to the PR.

@Rakshat28 Rakshat28 merged commit b7f4d7d into Rakshat28:main May 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: bdstorage status command — vault and deduplication summary

2 participants