hash: derive the occupancy survey from per-extent fragments
The prefetch-thread survey walked every cell of the table each interval to
build the page-occupancy histogram, counting both occupancy and a per-cell
type breakdown (compressed / unaligned_eof / toxic). With 256 cells per
bucket that is a full-table scan under per-extent locks every hour, and the
type breakdown reads v1 BeesAddress bits that scan-next neither sets on store
nor reads on fetch — so under scan-next those counters are structurally
meaningless.
Replace the walk with a cached per-extent occupancy fragment. Each
ExtentMetaData gains a small bucket-fill histogram (index = occupied cells in
a bucket, value = number of buckets at that occupancy). It is rebuilt under
the extent lock at two points that already touch the whole extent: the
startup load, and each writeback (where the extent is copied for pwrite).
Occupancy can only change when a cell is inserted or evicted, which dirties
the extent, so a writeback-time refresh captures every change; read-mostly
extents keep their load-time fragment. Staleness is bounded by the writeback
cycle, so the printed graph is effectively current with on-disk data.
The survey is now a sum over fragments with no cell walk and no locking
beyond a brief per-extent read. Drop the type breakdown and the percent()
helper that only formatted it; total cell count comes from m_cells directly.
verify_cell_range loses its last live caller but is left in place (now
referenced only from #if 0 blocks); removing it is a separate cleanup.