diff --git a/metrics/resetting_timer.go b/metrics/resetting_timer.go index 924ba11052..e5327d3bd3 100644 --- a/metrics/resetting_timer.go +++ b/metrics/resetting_timer.go @@ -2,10 +2,9 @@ package metrics import ( "math" + "sort" "sync" "time" - - "golang.org/x/exp/slices" ) // Initial slice capacity for the values stored in a ResettingTimer @@ -187,7 +186,7 @@ func (t *ResettingTimerSnapshot) Mean() float64 { } func (t *ResettingTimerSnapshot) calc(percentiles []float64) { - slices.Sort(t.values) + sort.Sort(Int64Slice(t.values)) count := len(t.values) if count > 0 { @@ -233,3 +232,10 @@ func (t *ResettingTimerSnapshot) calc(percentiles []float64) { t.calculated = true } + +// Int64Slice attaches the methods of sort.Interface to []int64, sorting in increasing order. +type Int64Slice []int64 + +func (s Int64Slice) Len() int { return len(s) } +func (s Int64Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s Int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } diff --git a/metrics/sample.go b/metrics/sample.go index 252a878f58..afcaa21184 100644 --- a/metrics/sample.go +++ b/metrics/sample.go @@ -3,10 +3,9 @@ package metrics import ( "math" "math/rand" + "sort" "sync" "time" - - "golang.org/x/exp/slices" ) const rescaleThreshold = time.Hour @@ -283,17 +282,17 @@ func SampleMin(values []int64) int64 { } // SamplePercentiles returns an arbitrary percentile of the slice of int64. -func SamplePercentile(values []int64, p float64) float64 { +func SamplePercentile(values int64Slice, p float64) float64 { return SamplePercentiles(values, []float64{p})[0] } // SamplePercentiles returns a slice of arbitrary percentiles of the slice of // int64. -func SamplePercentiles(values []int64, ps []float64) []float64 { +func SamplePercentiles(values int64Slice, ps []float64) []float64 { scores := make([]float64, len(ps)) size := len(values) if size > 0 { - slices.Sort(values) + sort.Sort(values) for i, p := range ps { pos := p * float64(size+1) if pos < 1.0 { @@ -634,3 +633,9 @@ func (h *expDecaySampleHeap) down(i, n int) { i = j } } + +type int64Slice []int64 + +func (p int64Slice) Len() int { return len(p) } +func (p int64Slice) Less(i, j int) bool { return p[i] < p[j] } +func (p int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/metrics/writer.go b/metrics/writer.go index 3d60485b6b..256fbd14c9 100644 --- a/metrics/writer.go +++ b/metrics/writer.go @@ -3,9 +3,8 @@ package metrics import ( "fmt" "io" + "sort" "time" - - "golang.org/x/exp/slices" ) // Write sorts writes each metric in the given registry periodically to the @@ -19,12 +18,12 @@ func Write(r Registry, d time.Duration, w io.Writer) { // WriteOnce sorts and writes metrics in the given registry to the given // io.Writer. func WriteOnce(r Registry, w io.Writer) { - var namedMetrics []namedMetric + var namedMetrics namedMetricSlice r.Each(func(name string, i interface{}) { namedMetrics = append(namedMetrics, namedMetric{name, i}) }) - slices.SortFunc(namedMetrics, namedMetric.less) + sort.Sort(namedMetrics) for _, namedMetric := range namedMetrics { switch metric := namedMetric.m.(type) { case Counter: @@ -92,6 +91,13 @@ type namedMetric struct { m interface{} } -func (m namedMetric) less(other namedMetric) bool { - return m.name < other.name +// namedMetricSlice is a slice of namedMetrics that implements sort.Interface. +type namedMetricSlice []namedMetric + +func (nms namedMetricSlice) Len() int { return len(nms) } + +func (nms namedMetricSlice) Swap(i, j int) { nms[i], nms[j] = nms[j], nms[i] } + +func (nms namedMetricSlice) Less(i, j int) bool { + return nms[i].name < nms[j].name } diff --git a/metrics/writer_test.go b/metrics/writer_test.go index a4c92addc9..1aacc28712 100644 --- a/metrics/writer_test.go +++ b/metrics/writer_test.go @@ -1,20 +1,19 @@ package metrics import ( + "sort" "testing" - - "golang.org/x/exp/slices" ) func TestMetricsSorting(t *testing.T) { - var namedMetrics = []namedMetric{ + var namedMetrics = namedMetricSlice{ {name: "zzz"}, {name: "bbb"}, {name: "fff"}, {name: "ggg"}, } - slices.SortFunc(namedMetrics, namedMetric.less) + sort.Sort(namedMetrics) for i, name := range []string{"bbb", "fff", "ggg", "zzz"} { if namedMetrics[i].name != name { t.Fail()