Skip to content

Commit

Permalink
lttb: Fix LTTB bucketing and add better tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tsenart committed Jul 30, 2018
1 parent 15bec40 commit b313306
Show file tree
Hide file tree
Showing 3 changed files with 14,128 additions and 16 deletions.
40 changes: 26 additions & 14 deletions lib/lttb.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package vegeta

import "errors"

// a point in a line chart
type point struct{ x, y float64 }

Expand All @@ -12,19 +14,19 @@ type bucket []point
// https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf
func lttb(count, threshold int, iter func(count int) ([]point, error)) ([]point, error) {
if threshold >= count || threshold == 0 {
return iter(count)
points, err := iter(count)
return points, err
}

// Bucket size. Leave room for start and end data points
var size int
if threshold < 3 {
size = count - 2
} else {
size = (count - 2) / (threshold - 2)
return nil, errors.New("lttb: min threshold is 3")
}

// Bucket size. Leave room for start and end data points
size := float64(count-2) / float64(threshold-2)

// Get the first point and the current bucket.
points, err := iter(1 + size)
points, err := iter(int(1 + size))
if err != nil {
return nil, err
}
Expand All @@ -33,22 +35,32 @@ func lttb(count, threshold int, iter func(count int) ([]point, error)) ([]point,
samples = append(samples, points[0]) // Always add the first point
current := points[1:]

for len(samples) < (threshold - 1) {
next, err := iter(size)
for i := 0; i < threshold-2; i++ {
// Calculate bucket boundaries (non inclusive hi)
lo := int(float64(i+1)*size) + 1
hi := int(float64(i+2)*size) + 1

next, err := iter(hi - lo)
if err != nil {
return nil, err
}

if len(next) == 0 {
break
}

samples = append(samples, lttbSample(samples[len(samples)-1], current, next))
current = next
}

// Always add the last point unmodified
return append(samples, current[len(current)-1]), nil
if points, err = iter(count - len(samples)); err != nil {
return nil, err
} else if len(points) == 0 {
points = current
}

if len(points) > 0 {
samples = append(samples, points[len(points)-1])
}

return samples, nil
}

func lttbSample(a point, current, next bucket) (b point) {
Expand Down
Loading

0 comments on commit b313306

Please sign in to comment.