Copyright 2017, OpenCensus Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

package trace

import (
	
)
samplePeriod is the minimum time between accepting spans in a single bucket.
defaultLatencies contains the default latency bucket bounds. TODO: consider defaults, make configurable
bucket is a container for a set of spans for a particular error code or latency range.
type bucket struct {
	nextTime  time.Time   // next time we can accept a span
	buffer    []*SpanData // circular buffer of spans
	nextIndex int         // location next SpanData should be placed in buffer
	overflow  bool        // whether the circular buffer has wrapped around
}

func ( int) bucket {
	return bucket{
		buffer: make([]*SpanData, ),
	}
}
add adds a span to the bucket, if nextTime has been reached.
func ( *bucket) ( *SpanData) {
	if .EndTime.Before(.nextTime) {
		return
	}
	if len(.buffer) == 0 {
		return
	}
	.nextTime = .EndTime.Add(samplePeriod)
	.buffer[.nextIndex] = 
	.nextIndex++
	if .nextIndex == len(.buffer) {
		.nextIndex = 0
		.overflow = true
	}
}
size returns the number of spans in the bucket.
func ( *bucket) () int {
	if .overflow {
		return len(.buffer)
	}
	return .nextIndex
}
span returns the ith span in the bucket.
func ( *bucket) ( int) *SpanData {
	if !.overflow {
		return .buffer[]
	}
	if  < len(.buffer)-.nextIndex {
		return .buffer[.nextIndex+]
	}
	return .buffer[.nextIndex+-len(.buffer)]
}
resize changes the size of the bucket to n, keeping up to n existing spans.
func ( *bucket) ( int) {
	 := .size()
	 := make([]*SpanData, )
	if  <  {
		for  := 0;  < ; ++ {
			[] = .span()
		}
		.buffer = 
		.nextIndex = 
		.overflow = false
		return
	}
	for  := 0;  < ; ++ {
		[] = .span( +  - )
	}
	.buffer = 
	.nextIndex = 0
	.overflow = true
}
latencyBucket returns the appropriate bucket number for a given latency.
func ( time.Duration) int {
	 := 0
	for  < len(defaultLatencies) &&  >= defaultLatencies[] {
		++
	}
	return 
}
latencyBucketBounds returns the lower and upper bounds for a latency bucket number. The lower bound is inclusive, the upper bound is exclusive (except for the last bucket.)
func ( int) ( time.Duration,  time.Duration) {
	if  == 0 {
		return 0, defaultLatencies[]
	}
	if  == len(defaultLatencies) {
		return defaultLatencies[-1], 1<<63 - 1
	}
	return defaultLatencies[-1], defaultLatencies[]