nixbuild/util.go
Yonah 1e30aef337
derivation: collect store paths
The implementation of the main hack this library does.
2025-07-15 04:09:25 +09:00

57 lines
1.4 KiB
Go

package nixbuild
import (
"path"
"slices"
)
// this is pretty close to zero copy for the test case
const collectFromDerivationsInitialCap = 1 << 17
// CollectFromDerivations returns a deduplicated slice of store paths collected from derivations.
func CollectFromDerivations(derivations DerivationMap) []string {
var setpointSize, growToCap int
collective := make([]string, 0, collectFromDerivationsInitialCap)
for p, drv := range derivations {
if drv == nil {
// should be unreachable
continue
}
// another exponentially growing buffer here because range over map is expensive
setpointSize = len(collective) + len(drv.InputSources) +
// only map keys
len(drv.InputDerivations) +
// only Output.Path
len(drv.Outputs) +
// self, builder
2
if setpointSize > cap(collective) {
growToCap = cap(collective) << 1
tryGrow:
if setpointSize > growToCap {
// unlikely to be reached
growToCap <<= 1
goto tryGrow
}
collective = slices.Grow(collective, growToCap-cap(collective))
}
collective = append(collective, drv.InputSources...)
for s := range drv.InputDerivations {
collective = append(collective, s)
}
for _, out := range drv.Outputs {
collective = append(collective, out.Path)
}
collective = append(collective, p)
if path.IsAbs(drv.Builder) { // so builtins don't get collected
collective = append(collective, drv.Builder)
}
}
slices.Sort(collective)
return slices.Compact(collective)
}