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

The delete step of the layer GC, factored out of the `Gc` server so its
safety contracts are testable against a real database without the
cluster-singleton GenServer around them:

  * a missing blob still referenced by an image is *dangling* — reported,
    never deleted;
  * rows younger than `grace_period` are never deleted;
  * the `DELETE` re-checks `NOT EXISTS (image_layers)`, so a reference
    that appeared after the caller's snapshot is skipped, not violated;
  * the shared medium is re-probed before any delete, so a mount that
    vanished mid-page skips the page instead of mass-deleting;
  * `presence/1` maps only a true `:enoent` to `:missing`; any other I/O
    error is `:unknown` and never drives a delete.

Every query runs at low priority: in a transaction with a capped
per-statement timeout, so the GC can never pin a backend.

# `execute`

```elixir
@spec execute(Hyper.Cfg.Gc.t(), [Hyper.Img.Db.Gc.Sweep.blob()]) ::
  {non_neg_integer(), non_neg_integer(), non_neg_integer()}
```

Act on one page's missing set: re-check the medium is still mounted, split
dangling (still referenced) from prunable, delete what is out of grace.
Returns `{pruned, pruned_bytes, dangling}`.

# `presence`

```elixir
@spec presence(String.t()) :: Hyper.Img.Db.Gc.Sweep.presence()
```

Shared-medium presence probe injected into the pure Sweep core.
Distinguishes a genuine absence (`:enoent` -> prunable) from an I/O error
(`:unknown` -> never pruned), so a transient NFS hiccup can never drive a
delete.

# `with_low_priority`

```elixir
@spec with_low_priority(Hyper.Cfg.Gc.t(), (-&gt; result)) :: result when result: var
```

Run a DB operation at low priority: in a transaction with a capped
per-statement timeout, so it can never pin a backend and yields under
contention.

---

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