containerd/gc/2

70 lines
1.4 KiB
Plaintext

package gc
type color uint8
const (
white = iota
gray
black
)
func tricolor(roots []string, all []string, refs map[string][]string) []string {
// all objects white -> default value of color
state := make(map[string]color, len(all))
var (
grays []string
reachable []string
)
grays = append(grays, roots...)
// root-set objects gray.
for _, ro := range roots {
state[ro] = gray
}
// (Repeat this as long as there are gray coloured objects) Pick a gray
// object. Colour all objects referenced to from that gray object gray too.
// (Except those who are black). And colour itself black.
// Pick any gray object
for id := findcolor(state, gray); id != ""; id = findcolor(state, gray) {
// mark all the referenced objects as gray
for _, target := range refs[id] {
if state[target] == white {
state[target] = gray
}
}
state[id] = black
}
// All black objects are now reachable, and all white objects are
// unreachable. Free those that are white!
var whites []string
for _, obj := range all {
if state[obj] == white {
whites = append(whites, obj)
}
}
return whites
}
func findcolor(cs map[string]color, q color) string {
// TODO(stevvooe): Super-inefficient!
for id, c := range cs {
if c == q {
return id
}
}
return ""
}
// type colorset struct {
// state map[string]color
// }
// func (cs *colorset) mark(id string, c color) {
// cs.state[id] = c
// }