package nix 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) }