code: func makeHistogramBuilder(smooth func(float64) float64) HistogramBuilder {
  	return func(vals []float64) (buckets map[float64]uint64, sum float64) {
  		buckets = make(map[float64]uint64)
  		sort.Slice(vals, func(i, j int) bool { return vals[i] < vals[j] })
  
  		var count uint64
  		for _, upper := range vals {
  			count++
  			// Use unsmoothed value for sum so we get true value
  			sum += upper
  			// Use smoothed upper bound for buckets. Collisions here are fine since the count is cumulative so any
  			// earlier upper/count pairs that are overwritten will have their count captured in the overwriting count
  			buckets[smooth(upper)] = count
  		}
  		return buckets, sum
  	}
  }
docs: // Returns a function that builds a histogram.
  //
  // The builder takes a slice of values one for each entity in a sample, sorts it, and computes histogram buckets as
  // a map from upper bounds (of values) to cumulative counts (of entities)
  // such that count-many entities have value less than or equal to each upper bound.
  // Returns this map and the sum of all values.
  //
  // The smoothing function can be used to round up the upper bounds of buckets so that generated buckets fall on rounder
  // more predictable values. This can make querying for a specific bucket easier but not strictly necessary since we can
  // use histogram_quantile function in promql to aggregate buckets without needing to know upper bounds ahead of time.
  //
  // For example if we have the collection (people are entities, numbers of oranges are values)
  //
  // Fred: 12 oranges
  // Annie: 4 oranges
  // Paul: 1 orange
  //
  // We return:
  //
  // upper bound number of oranges => cumulative number of people (with less than or equal to upper bound number of oranges)
  // 1 => 1
  // 4 => 2
  // 12 => 3
  //
  // and 17 for the sum