PLAN: Space scans a disk or a pool, from a dropdown

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-22 20:28:00 -07:00
co-authored by Claude Fable 5.1
parent 8f77cc23e1
commit c96d6facad
+7 -5
View File
@@ -327,17 +327,19 @@ something long in one, switch away and back, refresh — it's all still there.
users`, `hamlab user-rm <user>`; `hamlab install` names the first account after the users`, `hamlab user-rm <user>`; `hamlab install` names the first account after the
service user. Not done: a read-only viewer role. service user. Not done: a read-only viewer role.
- **Space tab** — **shipped 2026-09-22** (`internal/space`, `internal/api/space.go`, - **Space tab** — **shipped 2026-09-22** (`internal/space`, `internal/api/space.go`,
`Space.tsx`), asked for as "exactly WizTree": what is using a disk. A **disk** is picked at `Space.tsx`), asked for as "exactly WizTree": what is using a disk. The unit is a whole
the top, not a partition: the scan covers every filesystem the disk backs — its partitions' volume, picked from a dropdown at the top: a **disk on its own** (every filesystem its
mountpoints, and for a disk in a ZFS pool every mounted dataset of the pool (any of `tank`'s partitions back) or a **ZFS pool as a whole** (every mounted dataset) — a pool's member
eight disks shows `tank`). The walk runs as a helper process, `hamlab space-walk <roots>`, disks are listed under it with the layout (raidz2, 8 disks: sda …) and never offered
apart, since one disk's share of a pool means nothing (Mitchell's call, same day, after a
first cut that listed the disks as chips). The walk runs as a helper process, `hamlab space-walk <roots>`,
as root through `priv` when the host allows (so `/var/lib/docker` and `/root` count), 32 as root through `priv` when the host allows (so `/var/lib/docker` and `/root` count), 32
workers reading directories depth-first, never crossing a filesystem boundary by itself; workers reading directories depth-first, never crossing a filesystem boundary by itself;
each root is grafted into one tree at its path. Files under 128 KiB are not kept one by one each root is grafted into one tree at its path. Files under 128 KiB are not kept one by one
but summed per folder as "N smaller files" — what keeps a scan of millions of files to tens but summed per folder as "N smaller files" — what keeps a scan of millions of files to tens
of MB in the daemon; the tree crosses back as a varint stream (`codec.go`), and the helper's of MB in the daemon; the tree crosses back as a varint stream (`codec.go`), and the helper's
memory goes with it. core's root: 646k files in ~1.2 s. Progress (files, bytes, current memory goes with it. core's root: 646k files in ~1.2 s. Progress (files, bytes, current
folder) every 250 ms; Cancel sends SIGTERM. The page: disk chips → Scan/Rescan → **Folders** folder) every 250 ms; Cancel sends SIGTERM. The page: picker → Scan/Rescan → **Folders**
(a tree largest-first: size, share of parent as a bar, files, folders, modified; expand in (a tree largest-first: size, share of parent as a bar, files, folders, modified; expand in
place) over a **treemap** of the selected folder — squarified, nested to the file, tiles place) over a **treemap** of the selected folder — squarified, nested to the file, tiles
coloured by kind (video, images, audio, archives & disk images, documents, code & config, coloured by kind (video, images, audio, archives & disk images, documents, code & config,