Skip to content

Commit

Permalink
adding percentile in histogram
Browse files Browse the repository at this point in the history
  • Loading branch information
aman-bansal committed Jan 27, 2021
1 parent bb5d392 commit 1b848e7
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
22 changes: 22 additions & 0 deletions z/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,25 @@ func (histogram *HistogramData) String() string {
b.WriteString(" --\n")
return b.String()
}

// Percentile returns the percentile value for the histogram.
// value of p should be between [0.0-1.0]
func (histogram *HistogramData) Percentile(p float64) float64 {
if histogram.Count == 0 {
// if no data return the minimum range
return histogram.Bounds[0]
}

pval := int64(float64(histogram.Count) * p)
for i, v := range histogram.CountPerBucket {
pval = pval - v
if pval <= 0 {
if i == len(histogram.Bounds) {
break
}
return histogram.Bounds[i]
}
}
// default return should be the max range
return histogram.Bounds[len(histogram.Bounds) - 1]
}
80 changes: 80 additions & 0 deletions z/histogram_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package z

import (
"github.com/stretchr/testify/require"
"math"
"testing"
)

func TestPercentile00(t *testing.T) {
size := int(math.Ceil((float64(514) - float64(32)) / float64(4)))
bounds := make([]float64, size + 1)
for i := range bounds {
if i == 0 {
bounds[0] = 32
continue
}
if i == size {
bounds[i] = 514
break
}
bounds[i] = bounds[i-1] + 4
}

h := NewHistogramData(bounds)
for v := 16; v <= 1024; v= v+4 {
for i:=0; i < 1000; i++ {
h.Update(int64(v))
}
}

require.Equal(t, h.Percentile(0.0), 32.0)
}

func TestPercentile99(t *testing.T) {
size := int(math.Ceil((float64(514) - float64(32)) / float64(4)))
bounds := make([]float64, size + 1)
for i := range bounds {
if i == 0 {
bounds[0] = 32
continue
}
if i == size {
bounds[i] = 514
break
}
bounds[i] = bounds[i-1] + 4
}
h := NewHistogramData(bounds)
for v := 16; v <= 1024; v= v+4 {
for i:=0; i < 1000; i++ {
h.Update(int64(v))
}
}

require.Equal(t, h.Percentile(0.99), 514.0)
}

func TestPercentile100(t *testing.T) {
size := int(math.Ceil((float64(514) - float64(32)) / float64(4)))
bounds := make([]float64, size + 1)
for i := range bounds {
if i == 0 {
bounds[0] = 32
continue
}
if i == size {
bounds[i] = 514
break
}
bounds[i] = bounds[i-1] + 4
}
h := NewHistogramData(bounds)
for v := 16; v <= 1024; v= v+4 {
for i:=0; i < 1000; i++ {
h.Update(int64(v))
}
}
require.Equal(t, h.Percentile(1.0), 514.0)
}

0 comments on commit 1b848e7

Please sign in to comment.