Expand description
Parallel directory scanner and snapshot pipeline behind the
rdirstat TUI and GUI.
rdirstat-core walks a filesystem in parallel, accumulates per-directory
sizes, and exposes the running state via UiSnapshots suitable for
consumption by an event-loop-driven UI. Both the terminal frontend
(rdirstat) and the desktop frontend
(rdirstat-gui) are built on
exactly this engine — no logic is duplicated between them.
§At a glance
start_scan() ──► walker thread ──► ScanState (live, atomic + Mutex)
│
└─► spawn_snapshot_thread()
─► UiSnapshot stream
─► your UI§Quick start
use std::path::PathBuf;
use std::sync::Arc;
use rdirstat_core::{ScanState, start_scan};
let state = ScanState::new();
start_scan(PathBuf::from("/tmp"), Arc::clone(&state));
// Block until the scan finishes (real frontends would poll a snapshot
// channel from their event loop instead).
while state.is_scanning() {
std::thread::sleep(std::time::Duration::from_millis(100));
}
println!("scanned {} files, {} bytes",
state.files_scanned(),
state.total_bytes.load(std::sync::atomic::Ordering::Relaxed));§Design properties worth knowing
- Allocated size, not logical size.
util::allocated_sizereturnsm.blocks() * 512on Unix, matchingdu’s default output. Sparse files report their real on-disk footprint; tiny files account for cluster rounding. - Inode deduplication. Hardlinks and macOS firmlinks (where
/Usersand/System/Volumes/Data/Usersalias the same inodes) are counted exactly once, regardless of how many paths point at them. - Honest “complete” status.
ScanState::is_completedonly returnstruewhen every file in a directory’s subtree has been counted — not the moment the walker finishes listing the directory’s immediate children.dir_sizes[D]is the final total at the momentDis marked complete. - Snapshot-driven UI. Frontends never read
ScanStatedirectly while rendering. They consume clonedUiSnapshots on a 100 ms cadence — seespawn_snapshot_thread— which makes the UI loop lock-free.
§Module map
| Module | Purpose |
|---|---|
scan | Parallel walker, ScanState, inode dedup, post-order completion |
snapshot | UiSnapshot type and the 100 ms snapshot pump |
app | AppState — directory navigation + scan controller for frontends |
model | DirEntry — one row in a directory listing |
mounts | list_mounts for drive-picker UIs |
util | allocated_size, format_size, strip_unc_prefix |
logging | Append-only file logger used by the binaries |
Re-exports§
pub use logging::init_logger;pub use logging::log;pub use util::allocated_size;pub use util::format_size;pub use util::strip_unc_prefix;pub use scan::ScanState;pub use scan::SizedEntry;pub use scan::ExtensionStat;pub use scan::start_scan;pub use mounts::MountPoint;pub use mounts::list_mounts;pub use model::DirEntry;pub use app::AppState;pub use snapshot::UiSnapshot;pub use snapshot::EntrySnapshot;pub use snapshot::spawn_snapshot_thread;
Modules§
- app
AppState— the controller layer between a frontend and the scan engine.- logging
- Append-only file logger used by the
rdirstatandrdirstat-guibinaries. - model
- The
DirEntryrow type used bycrate::AppStateto represent a single line in a directory listing. - mounts
- Cross-platform drive / mount-point enumeration for “pick a disk to scan” UIs.
- scan
- The parallel directory walker and the
ScanStateit writes into. - snapshot
- Lock-free, clone-on-tick view of the live
ScanStatefor the UI. - util
- Small free-standing helpers shared across the crate: allocated-size accounting, Windows UNC-path normalisation, and human-friendly byte formatting.