Skip to content

Commit

Permalink
fixes panic in the atomic package (#1245)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Hendriks committed Jan 25, 2021
1 parent 82949da commit b475b17
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
**/.idea/
.vscode
.run
venv

go.sum
Expand Down
47 changes: 31 additions & 16 deletions go/store/metrics/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package metrics

import (
"fmt"
"strconv"
"sync/atomic"
"time"

Expand All @@ -47,16 +48,20 @@ import (

const bucketCount = 64

type HistogramType uint64

const (
UnspecifiedHistogram HistogramType = iota
TimeHistogram
ByteHistogram
)

type Histogram struct {
// this structure needs to be a multiple of 8 bytes in size. This is necessary for 32-bit architectures and
// guarantees 8 byte alignment for multiple Histograms laid out side by side in memory.
sum uint64
buckets [bucketCount]uint64
ToString ToStringFunc
}

type ToStringFunc func(v uint64) string

func identToString(v uint64) string {
return fmt.Sprintf("%d", v)
histType HistogramType
}

// Sample adds a uint64 data point to the histogram
Expand Down Expand Up @@ -130,23 +135,33 @@ func (h Histogram) Samples() uint64 {
return s
}

func uintToString(v uint64) string {
return strconv.FormatUint(v, 10)
}

func timeToString(v uint64) string {
return time.Duration(v).String()
}

func (h Histogram) String() string {
f := h.ToString
if f == nil {
f = identToString
var f func(uint64) string
switch h.histType {
case UnspecifiedHistogram:
f = uintToString
case ByteHistogram:
f = humanize.Bytes
case TimeHistogram:
f = timeToString
}

return fmt.Sprintf("Mean: %s, Sum: %s, Samples: %d", f(h.Mean()), f(h.Sum()), h.Samples())
}

func NewTimeHistogram() Histogram {
return Histogram{ToString: timeToString}
}

func timeToString(v uint64) string {
return time.Duration(v).String()
return Histogram{histType: TimeHistogram}
}

// NewByteHistogram stringifies values using humanize over byte values
func NewByteHistogram() Histogram {
return Histogram{ToString: humanize.Bytes}
return Histogram{histType: ByteHistogram}
}
6 changes: 6 additions & 0 deletions go/store/metrics/histogram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package metrics

import (
"testing"
"unsafe"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -111,3 +112,8 @@ func TestHistogramString(t *testing.T) {
bh.Add(h)
assert.Equal("Mean: 758 MB, Sum: 3.0 GB, Samples: 4", bh.String())
}

func TestHistogramStructSize(t *testing.T) {
size := unsafe.Sizeof(Histogram{})
assert.True(t, size%8 == 0)
}

0 comments on commit b475b17

Please sign in to comment.