# `Hyper.Img.Db.Gc.Sweep`
[🔗](https://github.com/harmont-dev/hyper/blob/main/lib/hyper/img/db/gc/sweep.ex#L1)

Pure accounting core for the layer GC.

A `Hyper.Img.Db.Gc.Sweep.State` accumulates a single full pass over the `blobs`
table. `absorb/3` classifies a keyset page into present (file on the medium) vs
missing (file gone) and returns the missing blobs for the GC to prune;
`record_prune/4` folds the prune outcome back into the tally once the GC has
executed it against the database.

# `blob`

```elixir
@type blob() :: {String.t(), non_neg_integer()}
```

A blob page row: content-addressed id and its DB-recorded byte size.

# `check_fun`

```elixir
@type check_fun() :: (String.t() -&gt; presence())
```

# `presence`

```elixir
@type presence() :: :present | :missing | :unknown
```

Injected shared-medium probe. `:present` = file is there; `:missing` = file is
genuinely gone (safe to prune); `:unknown` = could not determine (I/O error),
so the blob is counted but never pruned.

# `absorb`

```elixir
@spec absorb(Hyper.Img.Db.Gc.Sweep.State.t(), [blob()], check_fun()) ::
  {Hyper.Img.Db.Gc.Sweep.State.t(), [blob()]}
```

Fold one keyset page into the sweep. Advances `cursor` to the last blob's id
(so the next page starts after it), counts present / missing / unknown, and
returns only the genuinely-missing blobs (file confirmed absent) as `{id, size}`
for the GC to prune. `:unknown` rows (probe I/O error) are counted but never
returned, so an unreachable medium can never drive a delete.

# `continue?`

```elixir
@spec continue?([term()], pos_integer()) :: boolean()
```

Full page (`length == limit`) means more rows may remain; page again.

# `new`

```elixir
@spec new() :: Hyper.Img.Db.Gc.Sweep.State.t()
```

A fresh sweep state: nil cursor (start of table), zeroed counters.

# `record_prune`

```elixir
@spec record_prune(
  Hyper.Img.Db.Gc.Sweep.State.t(),
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer()
) :: Hyper.Img.Db.Gc.Sweep.State.t()
```

Fold the result of pruning one page back into the sweep: `pruned` rows deleted
totalling `pruned_bytes`, and `dangling` rows left in place (file gone but the
blob is still referenced by an image - a data-loss condition the GC reports but
must not delete).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
