75 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
| // Copyright The OpenTelemetry Authors
 | |
| // 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 zpages
 | |
| 
 | |
| import (
 | |
| 	"time"
 | |
| 
 | |
| 	sdktrace "go.opentelemetry.io/otel/sdk/trace"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	// defaultBucketCapacity is the default capacity for every bucket (latency or error based).
 | |
| 	defaultBucketCapacity = 10
 | |
| 	// samplePeriod is the minimum time between accepting spans in a single bucket.
 | |
| 	samplePeriod = time.Second
 | |
| )
 | |
| 
 | |
| // bucket is a container for a set of spans for latency buckets or errored spans.
 | |
| type bucket struct {
 | |
| 	nextTime  time.Time               // next time we can accept a span
 | |
| 	buffer    []sdktrace.ReadOnlySpan // circular buffer of spans
 | |
| 	nextIndex int                     // location next ReadOnlySpan should be placed in buffer
 | |
| 	overflow  bool                    // whether the circular buffer has wrapped around
 | |
| }
 | |
| 
 | |
| // newBucket returns a new bucket with the given capacity.
 | |
| func newBucket(capacity uint) *bucket {
 | |
| 	return &bucket{
 | |
| 		buffer: make([]sdktrace.ReadOnlySpan, capacity),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // add adds a span to the bucket, if nextTime has been reached.
 | |
| func (b *bucket) add(s sdktrace.ReadOnlySpan) {
 | |
| 	if s.EndTime().Before(b.nextTime) {
 | |
| 		return
 | |
| 	}
 | |
| 	if len(b.buffer) == 0 {
 | |
| 		return
 | |
| 	}
 | |
| 	b.nextTime = s.EndTime().Add(samplePeriod)
 | |
| 	b.buffer[b.nextIndex] = s
 | |
| 	b.nextIndex++
 | |
| 	if b.nextIndex == len(b.buffer) {
 | |
| 		b.nextIndex = 0
 | |
| 		b.overflow = true
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // len returns the number of spans in the bucket.
 | |
| func (b *bucket) len() int {
 | |
| 	if b.overflow {
 | |
| 		return len(b.buffer)
 | |
| 	}
 | |
| 	return b.nextIndex
 | |
| }
 | |
| 
 | |
| // spans returns the spans in this bucket.
 | |
| func (b *bucket) spans() []sdktrace.ReadOnlySpan {
 | |
| 	return append([]sdktrace.ReadOnlySpan(nil), b.buffer[0:b.len()]...)
 | |
| }
 |