2012-05-24 22:02:44 +04:00
|
|
|
/*
|
|
|
|
Copyright (c) 2012, Matt T. Proud
|
|
|
|
All rights reserved.
|
2012-05-20 01:59:25 +04:00
|
|
|
|
2012-05-24 22:02:44 +04:00
|
|
|
Use of this source code is governed by a BSD-style
|
|
|
|
license that can be found in the LICENSE file.
|
|
|
|
*/
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
package metrics
|
|
|
|
|
|
|
|
import (
|
2013-01-18 19:29:47 +04:00
|
|
|
. "github.com/matttproud/gocheck"
|
2012-05-20 01:59:25 +04:00
|
|
|
"github.com/matttproud/golang_instrumentation/maths"
|
|
|
|
"github.com/matttproud/golang_instrumentation/utility"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (s *S) TestAccumulatingBucketBuilderWithEvictOldest(c *C) {
|
|
|
|
var evictOldestThree EvictionPolicy = EvictOldest(3)
|
|
|
|
|
|
|
|
c.Assert(evictOldestThree, Not(IsNil))
|
|
|
|
|
|
|
|
bb := AccumulatingBucketBuilder(evictOldestThree, 5)
|
|
|
|
|
|
|
|
c.Assert(bb, Not(IsNil))
|
|
|
|
|
|
|
|
var b Bucket = bb()
|
|
|
|
|
|
|
|
c.Assert(b, Not(IsNil))
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 0 elements and 5 capacity] { }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(1)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 1 elements and 5 capacity] { 1.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(2)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 2 elements and 5 capacity] { 1.000000, 2.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(3)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 3 elements and 5 capacity] { 1.000000, 2.000000, 3.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(4)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 4 elements and 5 capacity] { 1.000000, 2.000000, 3.000000, 4.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(5)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 5 elements and 5 capacity] { 1.000000, 2.000000, 3.000000, 4.000000, 5.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(6)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 3 elements and 5 capacity] { 4.000000, 5.000000, 6.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
var bucket Bucket = b
|
|
|
|
|
|
|
|
c.Assert(bucket, Not(IsNil))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *S) TestAccumulatingBucketBuilderWithEvictAndReplaceWithAverage(c *C) {
|
|
|
|
var evictAndReplaceWithAverage EvictionPolicy = EvictAndReplaceWith(3, maths.Average)
|
|
|
|
|
|
|
|
c.Assert(evictAndReplaceWithAverage, Not(IsNil))
|
|
|
|
|
|
|
|
bb := AccumulatingBucketBuilder(evictAndReplaceWithAverage, 5)
|
|
|
|
|
|
|
|
c.Assert(bb, Not(IsNil))
|
|
|
|
|
|
|
|
var b Bucket = bb()
|
|
|
|
|
|
|
|
c.Assert(b, Not(IsNil))
|
|
|
|
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 0 elements and 5 capacity] { }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(1)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 1 elements and 5 capacity] { 1.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(2)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 2 elements and 5 capacity] { 1.000000, 2.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(3)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 3 elements and 5 capacity] { 1.000000, 2.000000, 3.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(4)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 4 elements and 5 capacity] { 1.000000, 2.000000, 3.000000, 4.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(5)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 5 elements and 5 capacity] { 1.000000, 2.000000, 3.000000, 4.000000, 5.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
|
|
|
|
b.Add(6)
|
2012-12-19 14:10:09 +04:00
|
|
|
c.Check(b.String(), Equals, "[AccumulatingBucket with 4 elements and 5 capacity] { 4.000000, 5.000000, 2.000000, 6.000000, }")
|
2012-05-20 01:59:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *S) TestAccumulatingBucket(c *C) {
|
|
|
|
var b AccumulatingBucket = AccumulatingBucket{
|
|
|
|
elements: make(utility.PriorityQueue, 0, 10),
|
|
|
|
maximumSize: 5,
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Check(b.elements, HasLen, 0)
|
|
|
|
c.Check(b.observations, Equals, 0)
|
|
|
|
c.Check(b.Observations(), Equals, 0)
|
|
|
|
|
|
|
|
b.Add(5.0)
|
|
|
|
|
|
|
|
c.Check(b.elements, HasLen, 1)
|
|
|
|
c.Check(b.observations, Equals, 1)
|
|
|
|
c.Check(b.Observations(), Equals, 1)
|
|
|
|
|
|
|
|
b.Add(6.0)
|
|
|
|
b.Add(7.0)
|
|
|
|
b.Add(8.0)
|
|
|
|
b.Add(9.0)
|
|
|
|
|
|
|
|
c.Check(b.elements, HasLen, 5)
|
|
|
|
c.Check(b.observations, Equals, 5)
|
|
|
|
c.Check(b.Observations(), Equals, 5)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *S) TestAccumulatingBucketValueForIndex(c *C) {
|
|
|
|
var b AccumulatingBucket = AccumulatingBucket{
|
|
|
|
elements: make(utility.PriorityQueue, 0, 100),
|
|
|
|
maximumSize: 100,
|
|
|
|
evictionPolicy: EvictOldest(50),
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := 0; i <= 100; i++ {
|
|
|
|
c.Assert(b.ValueForIndex(i), maths.IsNaN)
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:02:44 +04:00
|
|
|
/*
|
|
|
|
The bucket has only observed one item and contains now one item.
|
|
|
|
*/
|
2012-05-20 01:59:25 +04:00
|
|
|
b.Add(1.0)
|
|
|
|
|
|
|
|
c.Check(b.ValueForIndex(0), Equals, 1.0)
|
2012-05-24 22:02:44 +04:00
|
|
|
/*
|
|
|
|
Let's sanity check what occurs if presumably an eviction happened and
|
|
|
|
we requested an index larger than what is contained.
|
|
|
|
*/
|
2012-05-20 01:59:25 +04:00
|
|
|
c.Check(b.ValueForIndex(1), Equals, 1.0)
|
|
|
|
|
|
|
|
for i := 2.0; i <= 100; i += 1 {
|
|
|
|
b.Add(i)
|
2012-05-24 22:02:44 +04:00
|
|
|
/*
|
|
|
|
TODO(mtp): This is a sin. Provide a mechanism for deterministic testing.
|
|
|
|
*/
|
2012-05-20 01:59:25 +04:00
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Check(b.ValueForIndex(0), Equals, 1.0)
|
2012-05-22 11:20:09 +04:00
|
|
|
c.Check(b.ValueForIndex(50), Equals, 50.0)
|
2012-05-20 01:59:25 +04:00
|
|
|
c.Check(b.ValueForIndex(100), Equals, 100.0)
|
|
|
|
|
|
|
|
for i := 101.0; i <= 150; i += 1 {
|
|
|
|
b.Add(i)
|
2012-05-24 22:02:44 +04:00
|
|
|
/*
|
|
|
|
TODO(mtp): This is a sin. Provide a mechanism for deterministic testing.
|
|
|
|
*/
|
2012-05-20 01:59:25 +04:00
|
|
|
time.Sleep(1 * time.Millisecond)
|
|
|
|
}
|
|
|
|
|
2012-05-24 22:02:44 +04:00
|
|
|
/*
|
|
|
|
The bucket's capacity has been exceeded by inputs at this point;
|
|
|
|
consequently, we search for a given element by percentage offset
|
|
|
|
therein.
|
|
|
|
*/
|
2012-05-20 01:59:25 +04:00
|
|
|
c.Check(b.ValueForIndex(0), Equals, 51.0)
|
2012-05-22 11:20:09 +04:00
|
|
|
c.Check(b.ValueForIndex(50), Equals, 84.0)
|
|
|
|
c.Check(b.ValueForIndex(99), Equals, 116.0)
|
|
|
|
c.Check(b.ValueForIndex(100), Equals, 117.0)
|
2012-05-20 01:59:25 +04:00
|
|
|
}
|