func (ts *timeSeries) Add(observation Observable) {
	ts.AddWithTime(observation, ts.clock.Time())
}
Add records an observation at the current time.
package timeseries  
import (
	"fmt"
	"log"
	"time"
)
const (
	timeSeriesNumBuckets       = 64
	minuteHourSeriesNumBuckets = 60
)
var timeSeriesResolutions = []time.Duration{
	1 * time.Second,
	10 * time.Second,
	1 * time.Minute,
	10 * time.Minute,
	1 * time.Hour,
	6 * time.Hour,
	24 * time.Hour,           
	7 * 24 * time.Hour,       
	4 * 7 * 24 * time.Hour,   
	16 * 7 * 24 * time.Hour,  
}
var minuteHourSeriesResolutions = []time.Duration{
	1 * time.Second,
	1 * time.Minute,
}
type Observable interface {
	Multiply(ratio float64)     
	Add(other Observable)       
	Clear()                     
	CopyFrom(other Observable)  
}
type Float float64
func NewFloat() Observable {
	f := Float(0)
	return &f
}
func (f *Float) String() string { return fmt.Sprintf("%g", f.Value()) }
func (f *Float) Value() float64 { return float64(*f) }
func (f *Float) Multiply(ratio float64) { *f *= Float(ratio) }
func (f *Float) Add(other Observable) {
	o := other.(*Float)
	*f += *o
}
func (f *Float) Clear() { *f = 0 }
func (f *Float) CopyFrom(other Observable) {
	o := other.(*Float)
	*f = *o
}
type Clock interface {
	Time() time.Time
}
type defaultClock int
var defaultClockInstance defaultClock
func (defaultClock) Time() time.Time { return time.Now() }
type tsLevel struct {
	oldest   int                
	newest   int                
	end      time.Time          
	size     time.Duration      
	buckets  []Observable       
	provider func() Observable  
}
func (l *tsLevel) Clear() {
	l.oldest = 0
	l.newest = len(l.buckets) - 1
	l.end = time.Time{}
	for i := range l.buckets {
		if l.buckets[i] != nil {
			l.buckets[i].Clear()
			l.buckets[i] = nil
		}
	}
}
func (l *tsLevel) InitLevel(size time.Duration, numBuckets int, f func() Observable) {
	l.size = size
	l.provider = f
	l.buckets = make([]Observable, numBuckets)
}
type timeSeries struct {
	provider    func() Observable  
	numBuckets  int                
	levels      []*tsLevel         
	lastAdd     time.Time          
	total       Observable         
	clock       Clock              
	pending     Observable         
	pendingTime time.Time          
	dirty       bool               
}
func (ts *timeSeries) init(resolutions []time.Duration, f func() Observable, numBuckets int, clock Clock) {
	ts.provider = f
	ts.numBuckets = numBuckets
	ts.clock = clock
	ts.levels = make([]*tsLevel, len(resolutions))
	for i := range resolutions {
		if i > 0 && resolutions[i-1] >= resolutions[i] {
			log.Print("timeseries: resolutions must be monotonically increasing")
			break
		}
		newLevel := new(tsLevel)
		newLevel.InitLevel(resolutions[i], ts.numBuckets, ts.provider)
		ts.levels[i] = newLevel
	}
	ts.Clear()
}
func (ts *timeSeries) Clear() {
	ts.lastAdd = time.Time{}
	ts.total = ts.resetObservation(ts.total)
	ts.pending = ts.resetObservation(ts.pending)
	ts.pendingTime = time.Time{}
	ts.dirty = false
	for i := range ts.levels {
		ts.levels[i].Clear()
	}
}