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 // }