func (f FloatVar) Avg() float64 {
	return f.Sum / float64(f.Count)
}
Avg computes the average of this random variable. Returns NaN if this
instance is empty (Count == 0).
package store
import (
	"errors"
	"github.com/Symantec/scotty/metrics"
	"github.com/Symantec/scotty/tsdb"
	"github.com/Symantec/tricorder/go/tricorder"
	"github.com/Symantec/tricorder/go/tricorder/types"
	"github.com/Symantec/tricorder/go/tricorder/units"
	"time"
)
var (
	ErrInactive = errors.New("store: endpoint inactive.")
)
type DistributionTotals struct {
	Counts        []uint64
	Sum           float64
	RollOverCount uint64
}
func (d *DistributionTotals) Count() (result uint64) {
	for _, count := range d.Counts {
		result += count
	}
	return
}
type Ranges struct {
	UpperLimits []float64
}
type MetricInfo struct {
	path        string
	description string
	unit        units.Unit
	kind        types.Type
	subType     types.Type
	ranges          *Ranges
	isNotCumulative bool
	groupId         int
}
func (m *MetricInfo) Path() string {
	return m.path
}
func (m *MetricInfo) Description() string {
	return m.description
}
func (m *MetricInfo) Unit() units.Unit {
	return m.unit
}
func (m *MetricInfo) Kind() types.Type {
	return m.kind
}
func (m *MetricInfo) SubType() types.Type {
	return m.subType
}
func (m *MetricInfo) Bits() int {
	if m.kind.UsesSubType() {
		return m.subType.Bits()
	}
	return m.kind.Bits()
}
func (m *MetricInfo) Ranges() *Ranges {
	return m.ranges
}
func (m *MetricInfo) IsNotCumulative() bool {
	return m.isNotCumulative
}
func (m *MetricInfo) GroupId() int {
	return m.groupId
}
func (m *MetricInfo) ValuesAreEqual(lhs, rhs interface{}) bool {
	return m.valuesAreEqual(lhs, rhs)
}
func (m *MetricInfo) Key() interface{} {
	var result MetricInfoBuilder
	result.Init(m)
	result.GroupId = 0
	return result
}
type MetricInfoBuilder struct {
	Path            string
	Description     string
	Unit            units.Unit
	Kind            types.Type
	SubType         types.Type
	Ranges          *Ranges
	IsNotCumulative bool
	GroupId         int
}
func (m *MetricInfoBuilder) Init(info *MetricInfo) {
	m.Path = info.Path()
	m.Description = info.Description()
	m.Unit = info.Unit()
	m.Kind = info.Kind()
	m.SubType = info.SubType()
	m.Ranges = info.ranges
	m.IsNotCumulative = info.isNotCumulative
	m.GroupId = info.GroupId()
}
func (m *MetricInfoBuilder) Build() *MetricInfo {
	return &MetricInfo{
		path:            m.Path,
		description:     m.Description,
		unit:            m.Unit,
		kind:            m.Kind,
		subType:         m.SubType,
		ranges:          m.Ranges,
		isNotCumulative: m.IsNotCumulative,
		groupId:         m.GroupId}
}
type MetricGroupingStrategy func(*MetricInfo) interface{}
var (
	GroupMetricExactly MetricGroupingStrategy = func(m *MetricInfo) interface{} {
		return m
	}
	GroupMetricByKey MetricGroupingStrategy = func(m *MetricInfo) interface{} {
		return m.Key()
	}
	GroupMetricByPathAndNumeric MetricGroupingStrategy = func(
		m *MetricInfo) interface{} {
		return pathAndNumeric{
			Path:      m.Path(),
			IsNumeric: m.Kind().CanToFromFloat(),
		}
	}
)
func (m MetricGroupingStrategy) Equal(
	maybeNilLeft, maybeNilRight *MetricInfo) bool {
	if maybeNilLeft == maybeNilRight {
		return true
	}
	if maybeNilLeft == nil || maybeNilRight == nil {
		return false
	}
	return m(maybeNilLeft) == m(maybeNilRight)
}
type Record struct {
	EndpointId interface{}
	Info       *MetricInfo
	TimeStamp  float64
	Value interface{}
	Active bool
}
type Filterer interface {
	Filter(*Record) bool
}
type TypeFilterer interface {
	Filterer
	FilterByType(info *MetricInfo) bool
}
type TypeFiltererFuncActiveOnly func(*MetricInfo) bool
func (f TypeFiltererFuncActiveOnly) FilterByType(m *MetricInfo) bool {
	return f(m)
}
func (f TypeFiltererFuncActiveOnly) Filter(r *Record) bool {
	return f(r.Info) && r.Active
}
type FiltererFunc func(*Record) bool
func (f FiltererFunc) Filter(r *Record) bool {
	return f(r)
}
type Appender interface {
	Append(r *Record) bool
}
type AppendFlusher interface {
	Appender
	Flush()
}
func AppendTo(result *[]Record) Appender {
	return (*recordListType)(result)
}
func AppenderFilterFunc(wrapped Appender, filter func(*Record) bool) Appender {
	return &filterAppenderType{
		filter: FiltererFunc(filter), wrapped: wrapped}
}
func AppenderLimit(wrapped Appender, limit int) Appender {
	if limit > 0 {
		return &limitAppenderType{limit: limit, wrapped: wrapped}
	}
	return wrapped
}
type Visitor interface {
	Visit(store *Store, endpoint interface{}) error
}
type Iterator interface {
	Next(r *Record) bool
}
func IteratorFilterFunc(
	iterator Iterator, filter func(*Record) bool) Iterator {
	return &filterIteratorType{
		filter:  FiltererFunc(filter),
		wrapped: iterator}
}
func IteratorFilter(
	iterator Iterator, filter Filterer) Iterator {
	return &filterIteratorType{
		filter:  filter,
		wrapped: iterator}
}
func IteratorCoordinate(
	iterator Iterator,
	coord Coordinator,
	minLeaseSpanInSeconds float64,
	skipped *uint64) Iterator {
	if minLeaseSpanInSeconds <= 0.0 {
		panic(minLeaseSpanInSeconds)
	}
	return &coordinatorIteratorType{
		coordinator: coord,
		wrapped:     iterator,
		leaseSpan:   minLeaseSpanInSeconds,
		skipped:     skipped,
	}
}
func NamedIteratorFilterFunc(
	ni NamedIterator, filter func(*Record) bool) NamedIterator {
	return &changedNamedIteratorType{
		NamedIterator: ni,
		change:        IteratorFilterFunc(ni, filter)}
}
func NamedIteratorFilter(
	ni NamedIterator, filter Filterer) NamedIterator {
	return namedIteratorFilter(ni, filter)
}
func NamedIteratorCoordinate(
	ni NamedIterator,
	coord Coordinator,
	minLeaseSpanInSeconds float64,
	updateSkipped func(uint64)) NamedIterator {
	result := &coordinatorNamedIteratorType{
		wrapped:       ni,
		updateSkipped: updateSkipped,
	}
	result.change = IteratorCoordinate(
		ni, coord, minLeaseSpanInSeconds, &result.skippedSoFar)
	return result
}
type NamedIterator interface {
	Name() string
	Next(r *Record) bool
	Commit()
}
type Store struct {
	byApplication map[interface{}]*timeSeriesCollectionType
	supplier      *pageQueueType
	metrics       *storeMetricsType
}
func NewStore(
	valueCount,
	pageCount uint,
	inactiveThreshhold float64,
	degree uint) *Store {
	return NewStoreBytesPerPage(
		valueCount*kTsAndValueSize,
		pageCount,
		inactiveThreshhold,
		degree)
}
func NewStoreBytesPerPage(
	bytesPerPage,
	pageCount uint,
	inactiveThreshhold float64,
	degree uint) *Store {
	return &Store{
		byApplication: make(map[interface{}]*timeSeriesCollectionType),
		supplier: newPageQueueType(
			bytesPerPage,
			pageCount,
			inactiveThreshhold,
			degree),
		metrics: newStoreMetricsType(),
	}
}
func (s *Store) LessenPageCount(ratio float64) {
	s.supplier.LessenPageCount(ratio)
}
func (s *Store) FreeUpBytes(bytesToFree uint64) {
	s.supplier.FreeUpBytes(bytesToFree)
}
func (s *Store) SetExpanding(expanding bool) {
	s.supplier.SetExpanding(expanding)
}
func (s *Store) IsExpanding() bool {
	return s.supplier.IsExpanding()
}
func (s *Store) ShallowCopy() *Store {
	return s.shallowCopy()
}
func (s *Store) RegisterEndpoint(endpointId interface{}) {
	s.registerEndpoint(endpointId)
}
func (s *Store) IsRegistered(endpointId interface{}) bool {
	return s.isRegistered(endpointId)
}
func (s *Store) AddBatch(
	endpointId interface{},
	timestamp float64,
	metricList metrics.List) (numAdded uint, err error) {
	return s.addBatch(endpointId, timestamp, metricList)
}
func (s *Store) ByNameAndEndpoint(
	path string,
	endpointId interface{},
	start, end float64,
	result Appender) {
	s.byNameAndEndpoint(
		path,
		endpointId,
		start,
		end,
		GroupMetricExactly,
		result)
}
func (s *Store) ByNameAndEndpointStrategy(
	path string,
	endpointId interface{},
	start, end float64,
	strategy MetricGroupingStrategy,
	result Appender) {
	s.byNameAndEndpoint(
		path,
		endpointId,
		start,
		end,
		strategy,
		result)
}
func (s *Store) ByPrefixAndEndpoint(
	prefix string,
	endpointId interface{},
	start, end float64,
	result Appender) {
	s.byPrefixAndEndpoint(
		prefix,
		endpointId,
		start,
		end,
		GroupMetricExactly,
		result)
}
func (s *Store) ByPrefixAndEndpointStrategy(
	prefix string,
	endpointId interface{},
	start, end float64,
	strategy MetricGroupingStrategy,
	result Appender) {
	s.byPrefixAndEndpoint(
		prefix,
		endpointId,
		start,
		end,
		strategy,
		result)
}
func (s *Store) ByEndpoint(
	endpointId interface{},
	start, end float64,
	result Appender) {
	s.byEndpoint(
		endpointId,
		start,
		end,
		GroupMetricExactly,
		result)
}
func (s *Store) ByEndpointStrategy(
	endpointId interface{},
	start, end float64,
	strategy MetricGroupingStrategy,
	result Appender) {
	s.byEndpoint(
		endpointId,
		start,
		end,
		strategy,
		result)
}
func (s *Store) Earliest(name string, endpointId interface{}) float64 {
	return s.byApplication[endpointId].Earliest(name)
}
func (s *Store) TsdbTimeSeries(
	name string,
	endpointId interface{},
	start, end float64) (result tsdb.TimeSeries, earliest float64, ok bool) {
	return s.tsdbTimeSeries(name, endpointId, start, end)
}
type FloatVar struct {
	Sum   float64
	Count uint64
}