code: func getDisambiguatedNames(g *graph.Graph) map[*graph.Node]string {
  	nodeName := make(map[*graph.Node]string, len(g.Nodes))
  
  	type names struct {
  		file, function string
  	}
  
  	// nameFunctionIndex maps the callgrind names (filename, function)
  	// to the node.Function values found for that name, and each
  	// node.Function value to a sequential index to be used on the
  	// disambiguated name.
  	nameFunctionIndex := make(map[names]map[*graph.Node]int)
  	for _, n := range g.Nodes {
  		nm := names{n.Info.File, n.Info.Name}
  		p, ok := nameFunctionIndex[nm]
  		if !ok {
  			p = make(map[*graph.Node]int)
  			nameFunctionIndex[nm] = p
  		}
  		if _, ok := p[n.Function]; !ok {
  			p[n.Function] = len(p)
  		}
  	}
  
  	for _, n := range g.Nodes {
  		nm := names{n.Info.File, n.Info.Name}
  		nodeName[n] = n.Info.Name
  		if p := nameFunctionIndex[nm]; len(p) > 1 {
  			// If there is more than one function, add suffix to disambiguate.
  			nodeName[n] += fmt.Sprintf(" [%d/%d]", p[n.Function]+1, len(p))
  		}
  	}
  	return nodeName
  }
docs: // getDisambiguatedNames returns a map from each node in the graph to
  // the name to use in the callgrind output. Callgrind merges all
  // functions with the same [file name, function name]. Add a [%d/n]
  // suffix to disambiguate nodes with different values of
  // node.Function, which we want to keep separate. In particular, this
  // affects graphs created with --call_tree, where nodes from different
  // contexts are associated to different Functions.