diff --git a/sdk/trace/evictedqueue.go b/sdk/trace/evictedqueue.go index 3c5817a6a02..8e89e19d4b9 100644 --- a/sdk/trace/evictedqueue.go +++ b/sdk/trace/evictedqueue.go @@ -14,24 +14,25 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace" +// evictedQueue is a FIFO queue with a configurable capacity. type evictedQueue struct { queue []interface{} capacity int droppedCount int } -func newEvictedQueue(capacity int) *evictedQueue { - eq := &evictedQueue{ - capacity: capacity, - queue: make([]interface{}, 0), - } - - return eq +func newEvictedQueue(capacity int) evictedQueue { + // Do not pre-allocate queue, do this lazily. + return evictedQueue{capacity: capacity} } +// add adds value to the evictedQueue eq. If eq is at capacity, the oldest +// queued value will be discarded and the drop count incremented. func (eq *evictedQueue) add(value interface{}) { if len(eq.queue) == eq.capacity { - eq.queue = eq.queue[1:] + // Drop first-in while avoiding allocating more capacity to eq.queue. + copy(eq.queue[:eq.capacity-1], eq.queue[1:]) + eq.queue = eq.queue[:eq.capacity-1] eq.droppedCount++ } eq.queue = append(eq.queue, value) diff --git a/sdk/trace/span.go b/sdk/trace/span.go index 41a68b58551..0111c475895 100644 --- a/sdk/trace/span.go +++ b/sdk/trace/span.go @@ -142,10 +142,10 @@ type recordingSpan struct { attributes *attributesMap // events are stored in FIFO queue capped by configured limit. - events *evictedQueue + events evictedQueue // links are stored in FIFO queue capped by configured limit. - links *evictedQueue + links evictedQueue // executionTracerTaskEnd ends the execution tracer span. executionTracerTaskEnd func()