A high-performance, concurrency-safe desktop systems tool for Linux that concurrently scans filesystem hierarchies, indexes metadata locally with SQLite, classifies system vs user assets, detects duplicates and stale files, forecasts disk usage growth, and executes human-confirmed cleanup actions safely.
View Text Architecture ASCII Diagram
ββββββββββββββββββββββββββββββββββββββββββ β Desktop GUI Shell (Wails v2) β β (HTML5 / CSS3 / Vanilla JS) β βββββββββββββββββββββ¬βββββββββββββββββββββ β HTTP / REST βΌ βββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββ β Python Layer (Analytics & ML) ββββΊβ Go Systems Core (HTTP API) β β Time-Series Growth Forecasting β β Port: 127.0.0.1:8080 β βββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββ¬ββββββββββββββββββββ β ββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββ βΌ βΌ βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ β Concurrent FS Scanner β β Action & Safety Engine β β β’ Bounded Worker Pool β β β’ Pre-action Inode Gate β β β’ VFS / Inode Stat Extr. β β β’ FreeDesktop XDG Trash β β β’ Two-Pass Deduplication β β β’ Immutable Audit Logger β ββββββββββββββββ¬βββββββββββββββ ββββββββββββββββ¬βββββββββββββββ β β β βββββββββββββββββββββββββββββββββββββββββββββ β βββββββββΊβ Channel Funnel (chan models.FileMetadata) ββββββββββ βββββββββββββββββββββββ¬ββββββββββββββββββββββ β βΌ βββββββββββββββββββββββββββββ β DB BatchWriter Goroutine β (Single Writer) βββββββββββββββ¬ββββββββββββββ β βΌ βββββββββββββββββββββββββββββ β SQLite DB (WAL Mode) β β data/optimizer.db β βββββββββββββββββββββββββββββ ```- Bounded Worker Pool: Discovers directories recursively and queues them into a bounded work channel (
chan string). Workers (NumWorkers = runtime.NumCPU() * 2) consume directory paths in parallel, eliminating file descriptor exhaustion (EMFILE). - Low-Level Syscall Extraction: Uses
os.Lstat(avoiding circular symlink loops) and castsFileInfo.Sys()to*syscall.Stat_tto extract Linux Inode numbers (stat.Ino), device IDs (stat.Dev), atime (stat.Atim.Sec), and ctime (stat.Ctim.Sec). - Path Classification: Classifies every file upon discovery into 6 distinct categories (
system_protected,system_log,crash_dump,temp,system_cache,user) based on file extension and Linux system hierarchy rules. - Incremental Rescanning: On subsequent scans of the same path, the scanner checks existing records in SQLite. If
mtimeorsizehas changed, the file's hash is cleared to trigger re-computation. Missing files are marked asis_deleted = 1.
- Single-Writer Funnel Pattern: To eliminate SQLite concurrent write lock contention (
database is locked), worker goroutines never write to SQLite directly. They pushFileMetadatastructs into a buffered Go channel (chan FileMetadata, capacity5000). - Atomic Batch Writes: A dedicated
BatchWritergoroutine drains the channel and executes bulk UPSERTs inside atomic transactions (BEGIN IMMEDIATE TRANSACTION ... COMMIT) every 500 records or 50 milliseconds. - WAL Performance Tuning:
PRAGMA journal_mode = WAL;(Concurrent readers while writing).PRAGMA synchronous = NORMAL;(High write throughput without corrupting WAL).PRAGMA cache_size = -64000;(64 MB in-memory page cache).PRAGMA temp_store = MEMORY;(RAM-based sorting).
-
Pass 1 (Size Filtering): Groups active files by
size HAVING COUNT(*) > 1. Files with unique sizes across the storage pool are excluded immediately, saving 80β90% of disk read I/O. -
Pass 2 (Streaming Cryptographic Hashing): Files sharing identical sizes that lack a stored hash are processed in parallel using a bounded worker pool. Files are read through 64 KB streaming buffers (
io.CopyBufferwithcrypto/sha256), guaranteeing flat memory consumption even on massive files. -
Cluster Aggregation: Files sharing the same SHA-256 hash are grouped into
DuplicateGroupclusters. The oldest copy bymtimeis elected as the primary original (IsOriginal = true), and wasted bytes are computed as$\text{FileSize} \times (\text{Count} - 1)$ .
Ranks inactive and junk files on a normalized scale from
-
Inactivity Time (
$t_{\text{inactive}}$ ): Days elapsed since$\max(\text{atime}, \text{mtime})$ . -
Decay Rate (
$\lambda = 0.015$ ): 60 days$\approx 0.63$ , 180 days$\approx 0.95$ . -
Category Weights: Crash dumps (
$1.50$ ), Temporary files ($1.40$ ), and Caches ($1.25$ ) are prioritized. User documents/code ($0.85$ ) receive conservative scores. System protected files are locked at$0.00$ .
- Safety Pre-Checks:
- Absolute path validation against Linux system blocklists (
/etc,/usr,/boot,/lib,/sys,/proc,/dev). - Pre-execution filesystem check: compares current on-disk
InodeandSizeagainst database metadata to prevent TOCTOU race conditions.
- Absolute path validation against Linux system blocklists (
- FreeDesktop.org XDG Trash Standard: In
trashmode, files are moved to~/.local/share/Trash/files/and an RFC-compliant.trashinfometadata file is written to~/.local/share/Trash/info/, enabling native restoration via GNOME Files / Dolphin. - Restoration Engine: Restores trashed files back to their original disk paths, recreates parent directories if needed, updates the SQLite index, and marks the audit record as
restored. - Immutable Audit Trail: Every cleanup action is recorded in
actions_logwith file IDs, paths, sizes, action modes, and status.
- Runs on
127.0.0.1:8080using standard Gonet/http. - Serves live scan progress feeds, aggregate statistics, duplicate clusters, stale file lists, directory hierarchy lookups, snapshot histories, and action executions.
- Embeds and serves the production web frontend at
/.
- Consumes
/api/v1/snapshotsand/api/v1/statsover HTTP. - Fits time-series growth trajectories using linear and polynomial regression models.
- Estimates "days-until-full" based on current partition capacity and daily growth velocity.
- Generates plain-language cleanup recommendations.
- Dual-Mode Desktop Shell: Built with Wails v2 (linking native Linux
webkit2gtk-4.1), compiling down to an 8.3 MB executable that consumes only ~32 MB of RAM. - Modern Design: Apple Human Interface Guidelines (HIG) dark mode aesthetic with smooth animations, custom segmented controls, interactive charts, and real-time tab filtering (
βK).
storage-optimizer/
βββ go-core/ # Systems Core (Go 1.25+)
β βββ cmd/storage-optimizer/main.go # CLI entrypoint & server orchestrator
β βββ internal/
β β βββ models/models.go # Domain structs & category constants
β β βββ scanner/scanner.go # Concurrent walker, stat extractor, diff engine
β β βββ db/db.go # SQLite connection, WAL PRAGMAs, BatchWriter funnel
β β βββ dedup/dedup.go # 2-pass duplicate engine (streaming SHA-256)
β β βββ stale/stale.go # Exponential decay staleness scoring
β β βββ action/action.go # XDG Trash, deletion gates, restore, audit logger
β β βββ api/api.go # REST API routes & embedded frontend static server
β βββ go.mod
βββ gui/ # Desktop GUI (Wails v2 + Web Frontend)
β βββ frontend/ # HTML5, CSS3, Vanilla JS application
β β βββ index.html # Single-page application markup
β β βββ style.css # macOS HIG Dark theme styling
β β βββ app.js # State management, API hooks & charts
β βββ wails.json
βββ python-layer/ # Analytics & Forecasting Microservice
β βββ service.py # FastAPI service consuming Go REST API
β βββ forecast/ # Time-series growth regression
β βββ recommend/ # Rule-based cleanup recommendations
βββ shared/
β βββ schema.sql # Canonical SQLite schema (Single Source of Truth)
βββ data/
β βββ optimizer.db # Runtime SQLite database
βββ docs/ # In-depth technical guides (7 documents)
β βββ 01-architecture-and-design.md
β βββ 02-systems-programming-and-linux.md
β βββ 03-concurrency-and-data-flow.md
β βββ 04-database-and-schema.md
β βββ 05-api-and-python-gui-contract.md
β βββ 06-operations-and-cli.md
β βββ 07-go-core-modules-guide.md
β βββ README.md
βββ README.md
Run the entire ecosystem (Go Systems Core + Python ML Layer) concurrently with a single command:
./start.sh# 1. Build Go Systems Core CLI
cd go-core
go build -o bin/dentry cmd/storage-optimizer/main.go
# 2. Build Frontend Distribution
cd ../gui/frontend
npm install && npm run build# Scan and index a directory hierarchy (with incremental sync & pruning)
./bin/dentry scan /path/to/scan --workers 16
# Find duplicate files and calculate wasted disk space
./bin/dentry duplicates --limit 50
# List stale and inactive files untouched for N days
./bin/dentry stale --days 60 --limit 100
# View historical scan snapshots
./bin/dentry snapshots
# Start local HTTP REST API server and web UI
./bin/dentry serve --port 8080
# Move files to FreeDesktop XDG Trash (~/.local/share/Trash/)
./bin/dentry delete --ids 101,102 --mode trash
# Permanently delete files (with audit logging)
./bin/dentry delete --ids 103 --mode permanent
# Restore a previously trashed file
./bin/dentry restore --id 1
# View immutable audit trail of past cleanup actions
./bin/dentry actions --limit 50| Method | Route | Description |
|---|---|---|
GET |
/api/v1/health |
Service health status and uptime |
GET |
/api/v1/stats |
Storage totals, duplicate bytes, and category breakdowns |
POST |
/api/v1/scan |
Trigger background filesystem scan ({"path":"...", "workers":12}) |
GET |
/api/v1/scan/status |
Live scan progress feed (file counts, current path, ETA) |
GET |
/api/v1/files/duplicates |
Paginated duplicate clusters sharing SHA-256 checksums |
GET |
/api/v1/files/duplicates/breakdown |
Top duplicate file extension breakdown analytics |
GET |
/api/v1/files/stale |
Ranked stale/inactive files by inactivity days |
GET |
/api/v1/files/stale/breakdown |
Top stale file extension breakdown analytics |
GET |
/api/v1/browse |
Lazy directory hierarchy navigation |
GET |
/api/v1/snapshots |
Historical scan snapshots for time-series charts |
POST |
/api/v1/actions |
Execute batch trash or permanent deletion |
POST |
/api/v1/actions/restore |
Restore trashed file back to disk |
GET |
/api/v1/actions/history |
Audit log records |
| Metric | Target Standard | Measured Benchmark (Linux NVMe) |
|---|---|---|
| Scan Throughput |
|
|
| Pass 1 Duplicate Filter |
|
|
| SHA-256 Buffer Memory | Constant RAM footprint |
|
| Database Contention |
|
|
| Binary Size & Memory |
|
|
For comprehensive deep-dives, consult the docs/ directory: