Documentation
¶
Overview ¶
Package diskcache holds the persistent disk render-cache Store and the single-flight, mtime-LRU sweep that bounds it. Store (store.go) owns the sharded layout, gzip framing, atomic writes, and eviction; the helm and kustomize render caches sit on it and add only their value codec. The sweep pieces here — the single-flight gate that keeps a burst of writes from forking one sweep per write, and the oldest-first eviction loop — are unexported; the only entry point is Store.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Store ¶ added in v0.4.4
type Store struct {
// contains filtered or unexported fields
}
Store is a persistent, cross-process disk cache of zstd-compressed byte payloads keyed by a content hash. Both render caches sit on it: the helm template-output cache (pkg/helm) stores rendered manifest bytes directly; the kustomize render cache (pkg/kustomize) stores a framed read-set + output and owns that framing on top. The Store owns everything below the value: the sharded on-disk layout, zstd compression, atomic writes, and the single-flight mtime-LRU sweep that bounds total bytes.
Layout under root:
<root>/<hex[:2]>/<hex>
where <hex> is the full hex-encoded sha256 cache key. The two-char shard avoids one giant directory (mkdir scan / readdir cost balloons past ~100k entries on common filesystems). Contents are zstd(payload).
Concurrency: Get is unsynchronized — the filesystem already serialises atomic-rename writes against partial reads. Put is likewise unsynchronized; the only coordination is the single-flight background sweep gated by sweepGate so a burst of Puts triggers one eviction pass instead of N. A nil *Store is the "caching disabled" sentinel: every method no-ops / misses, so call sites need not guard the wiring.
func NewStore ¶ added in v0.4.4
NewStore returns a disk-backed Store rooted at root with the supplied byte cap. A non-positive limit or empty root returns nil — the "caching disabled" sentinel the callers wire through.
The root is not created here; the first Put materialises it via rootOnce so we never leave an empty directory behind on disabled configurations.
func (*Store) Get ¶ added in v0.4.4
Get reads and decompresses the cached payload for key. Returns (nil, false) on any miss (including I/O / decompression errors — they're best-effort surfaced via slog Debug). A nil receiver is the "disabled" sentinel and silently misses.
Best-effort mtime bump: a successful read chtimes the file so the next sweep treats it as "recently used" (the OS atime is not a safe proxy on noatime filesystems). The bump is async-safe; a concurrent sweep already takes the sweep coordination flag.
func (*Store) Put ¶ added in v0.4.4
Put zstd-compresses payload and atomically writes it to the sharded path. Subsequent reads either observe the previous complete file or the new one — never a partial. After the write we kick a background sweep (single-flight via sweepGate) so the fast path doesn't block on directory walks.
nil-receiver no-ops so call sites can unconditionally Put without guarding the wiring constructor.