// addBenchDataToTile adds BenchData to a Tile.
//
// See the description at the top of this file for how the mapping works.
func addBenchDataToTile(benchData *BenchData, tile *tiling.Tile, offset int, counter metrics.Counter) {

	// cb is the anonymous closure we'll pass over all the trace values found in benchData.
	cb := func(key string, value float64, params map[string]string) {
		needsUpdate := false
		var trace *types.PerfTrace
		if tr, ok := tile.Traces[key]; !ok {
			trace = types.NewPerfTrace()
			tile.Traces[key] = trace
			needsUpdate = true
		} else {
			trace = tr.(*types.PerfTrace)
			if !util.MapsEqual(params, tile.Traces[key].Params()) {
				needsUpdate = true
			}
		}
		trace.Params_ = params
		trace.Values[offset] = value
		counter.Inc(1)

		if needsUpdate {
			// Update the Tile's ParamSet with any new keys or values we see.
			//
			// TODO(jcgregorio) Maybe defer this until we are about to Put the Tile
			// back to disk and rebuild ParamSet from scratch over all the Traces.
			for k, v := range params {
				if _, ok := tile.ParamSet[k]; !ok {
					tile.ParamSet[k] = []string{v}
				} else if !util.In(v, tile.ParamSet[k]) {
					tile.ParamSet[k] = append(tile.ParamSet[k], v)
				}
			}
		}
	}

	benchData.ForEach(cb)
}