Merge pull request #1973 from maier/master

vendor circonus
This commit is contained in:
Alex Dadgar 2016-11-09 16:47:38 -08:00 committed by GitHub
commit b63273b81f
2 changed files with 90 additions and 167 deletions

View file

@ -15,7 +15,7 @@ import (
) )
const ( const (
DEFAULT_HIST_SIZE = uint16(100) DEFAULT_HIST_SIZE = int16(100)
) )
var power_of_ten = [...]float64{ var power_of_ten = [...]float64{
@ -70,14 +70,6 @@ func NewBinFromFloat64(d float64) *Bin {
hb.SetFromFloat64(d) hb.SetFromFloat64(d)
return hb return hb
} }
type FastL2 struct {
l1, l2 int
}
func (hb *Bin) fastl2() FastL2 {
return FastL2{l1: int(uint8(hb.exp)), l2: int(uint8(hb.val))}
}
func (hb *Bin) SetFromFloat64(d float64) *Bin { func (hb *Bin) SetFromFloat64(d float64) *Bin {
hb.val = -1 hb.val = -1
if math.IsInf(d, 0) || math.IsNaN(d) { if math.IsInf(d, 0) || math.IsNaN(d) {
@ -125,7 +117,10 @@ func (hb *Bin) SetFromFloat64(d float64) *Bin {
return hb return hb
} }
func (hb *Bin) PowerOfTen() float64 { func (hb *Bin) PowerOfTen() float64 {
idx := int(uint8(hb.exp)) idx := int(hb.exp)
if idx < 0 {
idx = 256 + idx
}
return power_of_ten[idx] return power_of_ten[idx]
} }
@ -188,58 +183,69 @@ func (hb *Bin) Left() float64 {
} }
func (h1 *Bin) Compare(h2 *Bin) int { func (h1 *Bin) Compare(h2 *Bin) int {
var v1, v2 int if h1.val == h2.val && h1.exp == h2.exp {
return 0
// slide exp positive,
// shift by size of val
// multiple by (val != 0)
// then add or subtract val accordingly
if h1.val >= 0 {
v1 = ((int(h1.exp)+256)<<8)*int(((h1.val|(^h1.val+1))>>8)&1) + int(h1.val)
} else {
v1 = ((int(h1.exp)+256)<<8)*int(((h1.val|(^h1.val+1))>>8)&1) - int(h1.val)
} }
if h2.val >= 0 { if h1.val == -1 {
v2 = ((int(h2.exp)+256)<<8)*int(((h2.val|(^h2.val+1))>>8)&1) + int(h2.val) return 1
} else {
v2 = ((int(h2.exp)+256)<<8)*int(((h2.val|(^h2.val+1))>>8)&1) - int(h2.val)
} }
if h2.val == -1 {
// return the difference return -1
return v2 - v1 }
if h1.val == 0 {
if h2.val > 0 {
return 1
}
return -1
}
if h2.val == 0 {
if h1.val < 0 {
return 1
}
return -1
}
if h1.val < 0 && h2.val > 0 {
return 1
}
if h1.val > 0 && h2.val < 0 {
return -1
}
if h1.exp == h2.exp {
if h1.val < h2.val {
return 1
}
return -1
}
if h1.exp > h2.exp {
if h1.val < 0 {
return 1
}
return -1
}
if h1.exp < h2.exp {
if h1.val < 0 {
return -1
}
return 1
}
return 0
} }
// This histogram structure tracks values are two decimal digits of precision // This histogram structure tracks values are two decimal digits of precision
// with a bounded error that remains bounded upon composition // with a bounded error that remains bounded upon composition
type Histogram struct { type Histogram struct {
mutex sync.Mutex
bvs []Bin bvs []Bin
used uint16 used int16
allocd uint16 allocd int16
lookup [256][]uint16
mutex sync.Mutex
useLocks bool
} }
// New returns a new Histogram // New returns a new Histogram
func New() *Histogram { func New() *Histogram {
return &Histogram{ return &Histogram{
allocd: DEFAULT_HIST_SIZE, allocd: DEFAULT_HIST_SIZE,
used: 0, used: 0,
bvs: make([]Bin, DEFAULT_HIST_SIZE), bvs: make([]Bin, DEFAULT_HIST_SIZE),
useLocks: true,
}
}
// New returns a Histogram without locking
func NewNoLocks() *Histogram {
return &Histogram{
allocd: DEFAULT_HIST_SIZE,
used: 0,
bvs: make([]Bin, DEFAULT_HIST_SIZE),
useLocks: false,
} }
} }
@ -260,24 +266,9 @@ func (h *Histogram) Mean() float64 {
// Reset forgets all bins in the histogram (they remain allocated) // Reset forgets all bins in the histogram (they remain allocated)
func (h *Histogram) Reset() { func (h *Histogram) Reset() {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock()
defer h.mutex.Unlock()
}
for i := 0; i < 256; i++ {
if h.lookup[i] != nil {
for j := range h.lookup[i] {
h.lookup[i][j] = 0
}
}
}
h.used = 0 h.used = 0
} h.mutex.Unlock()
// RecordIntScale records an integer scaler value, returning an error if the
// value is out of range.
func (h *Histogram) RecordIntScale(val, scale int) error {
return h.RecordIntScales(val, scale, 1)
} }
// RecordValue records the given value, returning an error if the value is out // RecordValue records the given value, returning an error if the value is out
@ -313,19 +304,13 @@ func (h *Histogram) RecordCorrectedValue(v, expectedInterval int64) error {
} }
// find where a new bin should go // find where a new bin should go
func (h *Histogram) InternalFind(hb *Bin) (bool, uint16) { func (h *Histogram) InternalFind(hb *Bin) (bool, int16) {
if h.used == 0 { if h.used == 0 {
return false, 0 return false, 0
} }
f2 := hb.fastl2()
if h.lookup[f2.l1] != nil {
if idx := h.lookup[f2.l1][f2.l2]; idx != 0 {
return true, idx - 1
}
}
rv := -1 rv := -1
idx := uint16(0) idx := int16(0)
l := uint16(0) l := int16(0)
r := h.used - 1 r := h.used - 1
for l < r { for l < r {
check := (r + l) / 2 check := (r + l) / 2
@ -354,9 +339,10 @@ func (h *Histogram) InternalFind(hb *Bin) (bool, uint16) {
} }
func (h *Histogram) InsertBin(hb *Bin, count int64) uint64 { func (h *Histogram) InsertBin(hb *Bin, count int64) uint64 {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() defer h.mutex.Unlock()
defer h.mutex.Unlock() if count == 0 {
return 0
} }
found, idx := h.InternalFind(hb) found, idx := h.InternalFind(hb)
if !found { if !found {
@ -377,20 +363,13 @@ func (h *Histogram) InsertBin(hb *Bin, count int64) uint64 {
h.bvs[idx].exp = hb.exp h.bvs[idx].exp = hb.exp
h.bvs[idx].count = uint64(count) h.bvs[idx].count = uint64(count)
h.used++ h.used++
for i := idx; i < h.used; i++ {
f2 := h.bvs[i].fastl2()
if h.lookup[f2.l1] == nil {
h.lookup[f2.l1] = make([]uint16, 256)
}
h.lookup[f2.l1][f2.l2] = uint16(i) + 1
}
return h.bvs[idx].count return h.bvs[idx].count
} }
var newval uint64 var newval uint64
if count >= 0 { if count < 0 {
newval = h.bvs[idx].count + uint64(count)
} else {
newval = h.bvs[idx].count - uint64(-count) newval = h.bvs[idx].count - uint64(-count)
} else {
newval = h.bvs[idx].count + uint64(count)
} }
if newval < h.bvs[idx].count { //rolled if newval < h.bvs[idx].count { //rolled
newval = ^uint64(0) newval = ^uint64(0)
@ -399,39 +378,6 @@ func (h *Histogram) InsertBin(hb *Bin, count int64) uint64 {
return newval - h.bvs[idx].count return newval - h.bvs[idx].count
} }
// RecordIntScales records n occurrences of the given value, returning an error if
// the value is out of range.
func (h *Histogram) RecordIntScales(val, scale int, n int64) error {
sign := 1
if val == 0 {
scale = 0
} else {
if val < 0 {
val = 0 - val
sign = -1
}
if val < 10 {
val *= 10
scale -= 1
}
for val > 100 {
val /= 10
scale++
}
}
if scale < -128 {
val = 0
scale = 0
} else if scale > 127 {
val = 0xff
scale = 0
}
val *= sign
hb := Bin{val: int8(val), exp: int8(scale), count: 0}
h.InsertBin(&hb, n)
return nil
}
// RecordValues records n occurrences of the given value, returning an error if // RecordValues records n occurrences of the given value, returning an error if
// the value is out of range. // the value is out of range.
func (h *Histogram) RecordValues(v float64, n int64) error { func (h *Histogram) RecordValues(v float64, n int64) error {
@ -443,13 +389,11 @@ func (h *Histogram) RecordValues(v float64, n int64) error {
// Approximate mean // Approximate mean
func (h *Histogram) ApproxMean() float64 { func (h *Histogram) ApproxMean() float64 {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() defer h.mutex.Unlock()
defer h.mutex.Unlock()
}
divisor := 0.0 divisor := 0.0
sum := 0.0 sum := 0.0
for i := uint16(0); i < h.used; i++ { for i := int16(0); i < h.used; i++ {
midpoint := h.bvs[i].Midpoint() midpoint := h.bvs[i].Midpoint()
cardinality := float64(h.bvs[i].count) cardinality := float64(h.bvs[i].count)
divisor += cardinality divisor += cardinality
@ -463,12 +407,10 @@ func (h *Histogram) ApproxMean() float64 {
// Approximate sum // Approximate sum
func (h *Histogram) ApproxSum() float64 { func (h *Histogram) ApproxSum() float64 {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() defer h.mutex.Unlock()
defer h.mutex.Unlock()
}
sum := 0.0 sum := 0.0
for i := uint16(0); i < h.used; i++ { for i := int16(0); i < h.used; i++ {
midpoint := h.bvs[i].Midpoint() midpoint := h.bvs[i].Midpoint()
cardinality := float64(h.bvs[i].count) cardinality := float64(h.bvs[i].count)
sum += midpoint * cardinality sum += midpoint * cardinality
@ -477,12 +419,10 @@ func (h *Histogram) ApproxSum() float64 {
} }
func (h *Histogram) ApproxQuantile(q_in []float64) ([]float64, error) { func (h *Histogram) ApproxQuantile(q_in []float64) ([]float64, error) {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() defer h.mutex.Unlock()
defer h.mutex.Unlock()
}
q_out := make([]float64, len(q_in)) q_out := make([]float64, len(q_in))
i_q, i_b := 0, uint16(0) i_q, i_b := 0, int16(0)
total_cnt, bin_width, bin_left, lower_cnt, upper_cnt := 0.0, 0.0, 0.0, 0.0, 0.0 total_cnt, bin_width, bin_left, lower_cnt, upper_cnt := 0.0, 0.0, 0.0, 0.0, 0.0
if len(q_in) == 0 { if len(q_in) == 0 {
return q_out, nil return q_out, nil
@ -545,10 +485,8 @@ func (h *Histogram) ApproxQuantile(q_in []float64) ([]float64, error) {
// ValueAtQuantile returns the recorded value at the given quantile (0..1). // ValueAtQuantile returns the recorded value at the given quantile (0..1).
func (h *Histogram) ValueAtQuantile(q float64) float64 { func (h *Histogram) ValueAtQuantile(q float64) float64 {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() defer h.mutex.Unlock()
defer h.mutex.Unlock()
}
q_in := make([]float64, 1) q_in := make([]float64, 1)
q_in[0] = q q_in[0] = q
q_out, err := h.ApproxQuantile(q_in) q_out, err := h.ApproxQuantile(q_in)
@ -567,20 +505,16 @@ func (h *Histogram) SignificantFigures() int64 {
// Equals returns true if the two Histograms are equivalent, false if not. // Equals returns true if the two Histograms are equivalent, false if not.
func (h *Histogram) Equals(other *Histogram) bool { func (h *Histogram) Equals(other *Histogram) bool {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() other.mutex.Lock()
defer h.mutex.Unlock() defer h.mutex.Unlock()
} defer other.mutex.Unlock()
if other.useLocks {
other.mutex.Lock()
defer other.mutex.Unlock()
}
switch { switch {
case case
h.used != other.used: h.used != other.used:
return false return false
default: default:
for i := uint16(0); i < h.used; i++ { for i := int16(0); i < h.used; i++ {
if h.bvs[i].Compare(&other.bvs[i]) != 0 { if h.bvs[i].Compare(&other.bvs[i]) != 0 {
return false return false
} }
@ -593,10 +527,8 @@ func (h *Histogram) Equals(other *Histogram) bool {
} }
func (h *Histogram) CopyAndReset() *Histogram { func (h *Histogram) CopyAndReset() *Histogram {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() defer h.mutex.Unlock()
defer h.mutex.Unlock()
}
newhist := &Histogram{ newhist := &Histogram{
allocd: h.allocd, allocd: h.allocd,
used: h.used, used: h.used,
@ -605,20 +537,11 @@ func (h *Histogram) CopyAndReset() *Histogram {
h.allocd = DEFAULT_HIST_SIZE h.allocd = DEFAULT_HIST_SIZE
h.bvs = make([]Bin, DEFAULT_HIST_SIZE) h.bvs = make([]Bin, DEFAULT_HIST_SIZE)
h.used = 0 h.used = 0
for i := 0; i < 256; i++ {
if h.lookup[i] != nil {
for j := range h.lookup[i] {
h.lookup[i][j] = 0
}
}
}
return newhist return newhist
} }
func (h *Histogram) DecStrings() []string { func (h *Histogram) DecStrings() []string {
if h.useLocks { h.mutex.Lock()
h.mutex.Lock() defer h.mutex.Unlock()
defer h.mutex.Unlock()
}
out := make([]string, h.used) out := make([]string, h.used)
for i, bin := range h.bvs[0:h.used] { for i, bin := range h.bvs[0:h.used] {
var buffer bytes.Buffer var buffer bytes.Buffer

6
vendor/vendor.json vendored
View file

@ -218,10 +218,10 @@
"revisionTime": "2016-11-09T19:23:37Z" "revisionTime": "2016-11-09T19:23:37Z"
}, },
{ {
"checksumSHA1": "eYWKyMvUWZpmuXjDEIGy9lBddK0=", "checksumSHA1": "C4Z7+l5GOpOCW5DcvNYzheGvQRE=",
"path": "github.com/circonus-labs/circonusllhist", "path": "github.com/circonus-labs/circonusllhist",
"revision": "f3bb61c09a65a1bb5833219937fe4e7042dadab4", "revision": "365d370cc1459bdcaceda3499453668373dea1d0",
"revisionTime": "2016-11-09T20:01:07Z" "revisionTime": "2016-11-10T00:26:50Z"
}, },
{ {
"path": "github.com/davecgh/go-spew/spew", "path": "github.com/davecgh/go-spew/spew",