docs: correct the maxEntries remark for the HashSet and ring

The remark was written when the store was a Dictionary and the reclaim was
a full scan. Three things in it were stale:

It named a Dictionary capacity. HashSet and Dictionary share HashHelpers,
so the from-empty progression is identical (verified: 36,353 -> 75,431 ->
156,437 -> 324,449 -> 672,827 for both) and 324,449 is still exactly right
-- but it is a HashSet capacity now.

It priced a slot at 52 bytes. Measured, a HashSet<UInt128> slot is 36 and a
Dictionary<UInt128,long> slot is 52, so the total is ~19 MB at this cap (36
a set slot plus 24 a ring record), not ~17 MB.

It quoted full-sweep costs of ~6 ms here and ~26 ms at 968,897 as the price
of raising it. That sweep no longer exists; holds are retired from the ring
in expiry order, so the ceiling is memory rather than an on-loop scan.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kamron Batman 2026-08-13 23:18:32 -07:00
parent 5501c922ca
commit 3cc24128e3
No known key found for this signature in database
GPG key ID: 7D81DF26D9A5D94A

View file

@ -76,11 +76,12 @@ public record AutoDenylistSettings
/// disconnected by whichever gate detected them.
/// </summary>
/// <remarks>
/// A <c>Dictionary</c> capacity, not a round number. Grown from empty it steps 36,353 → 75,431 →
/// 156,437 → 324,449, so this fills one exactly instead of stranding slots: 65,536 sat just past a
/// resize and left 9,895 of them (52 bytes each) unusable. Sized to cover the 50k250k distinct-source
/// floods seen in practice, for ~17 MB. Raising it is paid on the loop, where a full sweep runs ~6 ms
/// here and ~26 ms at 968,897.
/// A <c>HashSet</c> capacity, not a round number. Grown from empty it steps 36,353 → 75,431 → 156,437
/// → 324,449, so this fills one exactly instead of stranding slots: 65,536 sat just past a resize and
/// left 9,895 of them unusable. Sized to cover the 50k250k distinct-source floods seen in practice,
/// for ~19 MB — 36 bytes a set slot plus 24 for the ring record. Raising it is bounded by memory
/// rather than by a scan, since holds are retired from the ring in expiry order; a flood past it wants
/// upstream scrubbing rather than a larger cap.
/// </remarks>
[JsonPropertyName("maxEntries")]
public int MaxEntries { get; set; } = 324_449;