From ec02e9ba191217fc31c6a27ef131ca9c51ae1425 Mon Sep 17 00:00:00 2001
From: Aliaksandr Valialkin <valyala@victoriametrics.com>
Date: Wed, 7 Feb 2024 21:43:24 +0200
Subject: [PATCH] lib/protoparser/datadogsketches: use math.RoundToEven() for
 calculating the rank

The original code uses this function - see https://github.com/DataDog/opentelemetry-mapping-go/blob/48d52eeea60d28da2e14c154a24557c4d290c6e2/pkg/quantile/sparse.go#L138

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5775
---
 lib/protoparser/datadogsketches/parser.go      |  2 +-
 lib/protoparser/datadogsketches/parser_test.go | 18 ++++++++++--------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/lib/protoparser/datadogsketches/parser.go b/lib/protoparser/datadogsketches/parser.go
index ec2b212686..9957f9d63e 100644
--- a/lib/protoparser/datadogsketches/parser.go
+++ b/lib/protoparser/datadogsketches/parser.go
@@ -303,7 +303,7 @@ func (d *Dogsketch) quantile(q float64) float64 {
 		return 0
 	}
 
-	rank := q * float64(d.Cnt-1)
+	rank := math.RoundToEven(q * float64(d.Cnt-1))
 	cnt := float64(0)
 	for i, n := range ns {
 		cnt += float64(n)
diff --git a/lib/protoparser/datadogsketches/parser_test.go b/lib/protoparser/datadogsketches/parser_test.go
index 161f073ef5..c9ea5eac35 100644
--- a/lib/protoparser/datadogsketches/parser_test.go
+++ b/lib/protoparser/datadogsketches/parser_test.go
@@ -9,21 +9,23 @@ func TestDogsketchQuantile(t *testing.T) {
 	f := func(d *Dogsketch, q float64, vExpected float64) {
 		t.Helper()
 		v := d.quantile(q)
-		if math.Abs(v-vExpected) > 0.4 {
+		if math.Abs(v-vExpected) > 0.01 {
 			t.Fatalf("unexpected value; got %v; want %v", v, vExpected)
 		}
 	}
 	sketches := &Dogsketch{
 		Min: 8.0,
-		Max: 20.0,
+		Max: 21.0,
 		Cnt: 17,
 		N:   []uint32{0x0, 0x0, 0x1, 0x0, 0x1, 0x4, 0x6, 0x1, 0x2, 0x0, 0x1, 0x0, 0x1},
 		K:   []int32{0, 1472, 1473, 1479, 1480, 1503, 1504, 1512, 1513, 1514, 1515, 1531, 1532},
 	}
-	f(sketches, 0.1, 8.96)
-	f(sketches, 0.5, 13.01)
-	f(sketches, 0.75, 14.96)
-	f(sketches, 0.9, 14.96)
-	f(sketches, 0.95, 15.43)
-	f(sketches, 0.99, 15.43)
+	f(sketches, 0, 8)
+	f(sketches, 0.1, 12.91)
+	f(sketches, 0.5, 13.18)
+	f(sketches, 0.75, 14.84)
+	f(sketches, 0.9, 15.19)
+	f(sketches, 0.95, 15.55)
+	f(sketches, 0.99, 20.24)
+	f(sketches, 1, 21)
 }