gocache

package
v1.2.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package gocache holds a Go build cache under a size: least recently used entries go first, never one used in the last Recent, never anything that is not a cache entry.

Go itself removes an entry only after five days unused, with no bound on size; a day of sprint cards grew one shared cache past 50 GiB, and a friend's per-job caches reached 9.3 GiB (ideas#833). Two callers hold a cache with it: the member's lazy round (cmd/nova-swarm/lazyclean.go), a few subdirectories at a time on its own clock, and nova-sprint friend clean (Hold), once a night over a friend's whole cache.

Index

Constants

View Source
const (
	Limit int64 = 20 * gib
	Slack int64 = Limit / 5
)

Limit is the size a cache is held under by default; once over it, a trim removes, oldest first, down to the low-water mark Slack under it (a fifth: 80% of the limit), and then removes nothing until the size passes the limit again. It was 10 GiB until 2026-10-04, when a busy 24-slot member wrote 13-14 GiB in three hours: every entry was under three hours old and the trim removed entries running builds still read, every round, and those builds failed (could not import ... go-build/...-d: no such file or directory). A busy machine names its own (nova-swarm member --gocache-limit, disk-guard --cache-max-gb).

View Source
const Recent = 2 * time.Hour

Recent is the default floor (Bounds.Floor): how recently used an entry is never removed, whatever the size. Go marks an entry used by setting its modification time, and only when that is over an hour old (the go command's cache package, its mtimeInterval), so an entry whose time is two hours old has not been used in the last hour: a build that just looked it up never finds it gone.

View Source
const SayEvery = time.Hour

SayEvery is how often a cache over its limit with every entry younger than the floor is said (Count.InUse): once an hour, never once a round.

View Source
const Subdirs = 256

Subdirs is the number of subdirectories of a Go build cache: two hex digits.

Variables

This section is empty.

Functions

func SlackOf

func SlackOf(limit int64) int64

SlackOf is the default slack of a limit: a fifth, so a trim stops at 80% of it.

Types

type Bounds

type Bounds struct {
	Limit, Slack int64
	Floor        time.Duration
	Dirs, Remove int
	Dry          bool
}

Bounds are a trim's limits. Floor is how recently used an entry is never removed (0: Recent); Dirs is how many subdirectories a round reads, Remove the most entries it removes; Dry counts what a round would remove and removes nothing.

type Count

type Count struct {
	Removed, Failed int
	Freed, Size     int64
	Why             string
	InUse           bool
}

Count is what one round did: entries removed (or, dry, that would be), removals failed (Why the first one's path and reason), the bytes freed and the cache's measured size. InUse says the cache is over its limit and every entry is younger than the floor, so nothing was removed: the limit is under the machine's working set. It is set at most once every SayEvery, so its caller says it then and never once a round.

func Hold

func Hold(dir string, now time.Time, b Bounds) Count

Hold measures the whole cache in one round and trims it in a second: a one-shot caller's trim, Dirs ignored. The measurement round runs first, over every subdirectory; the trim round re-reads them and suppresses re-reporting a failure the measurement already recorded (`t.failed[sub]`). That would swallow a shard that could not be read, so Hold carries the measurement round's failure count and first diagnostic into the returned Count. Removed and Freed still come from the trim round alone (the measurement round removes nothing: cutoff is math.MinInt64 until the cache is measured), and Size is the final measurement (docs/STANDARD.md, the silent rule; SPEC-CI.md, `silent`).

type Trim

type Trim struct {
	// contains filtered or unexported fields
}

Trim is the running measure of a cache and its trim. sizes and hours are each subdirectory's bytes, in all and by the hour (unix) of each entry's last use, as last read; measured counts the subdirectories read at least once (they are read in order from 00, so the first 256 reads measure them all); over is set when the measured size passed the limit and cleared when it fell to the limit less the slack.

func (*Trim) Round

func (t *Trim) Round(dir string, now time.Time, b Bounds) (c Count)

Round reads b.Dirs of the cache's subdirectories, the next ones in turn, and, once the whole cache has been measured and its size is over the limit, removes from those subdirectories the entries last used before the cutoff (cutoff) and at least the floor ago (b.Floor, else Recent), at most b.Remove a round, until the size is down to the low-water mark (the limit less the slack); then nothing until it passes the limit again. Oldest first, to the hour: Go records a use to the hour (Recent), so an entry's time is no finer than that. A missing entry is a cache miss that Go rebuilds, so removing an unused one costs at most a rebuild; removing one a running build still reads fails that build, so no entry younger than the floor is ever removed, whatever the size. A cache over its limit with every entry younger than the floor loses nothing, and the round says so (InUse) at most once every SayEvery.

func (*Trim) Total

func (t *Trim) Total() (n int64)

Total is the cache's measured size: the sum of its subdirectories' last reads.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL