*/ private array $buckets; public function __construct(int $size = 0) { $this->buckets = array_fill(0, $size, null); } /** * @param int|string $index * @param float|int $value */ public function store(int $bucket, $index, $value, AttributesInterface $attributes, ContextInterface $context, int $timestamp): void { assert($bucket <= count($this->buckets)); $exemplar = $this->buckets[$bucket] ??= new BucketEntry(); $exemplar->index = $index; $exemplar->value = $value; $exemplar->timestamp = $timestamp; $exemplar->attributes = $attributes; if (($spanContext = Span::fromContext($context)->getContext())->isValid()) { $exemplar->traceId = $spanContext->getTraceId(); $exemplar->spanId = $spanContext->getSpanId(); } else { $exemplar->traceId = null; $exemplar->spanId = null; } } /** * @param array $dataPointAttributes * @return array */ public function collect(array $dataPointAttributes): array { $exemplars = []; foreach ($this->buckets as $index => &$exemplar) { if (!$exemplar) { continue; } $exemplars[$index] = new Exemplar( $exemplar->index, $exemplar->value, $exemplar->timestamp, $this->filterExemplarAttributes( $dataPointAttributes[$exemplar->index], $exemplar->attributes, ), $exemplar->traceId, $exemplar->spanId, ); $exemplar = null; } return $exemplars; } private function filterExemplarAttributes(AttributesInterface $dataPointAttributes, AttributesInterface $exemplarAttributes): AttributesInterface { $attributes = []; foreach ($exemplarAttributes as $key => $value) { if ($dataPointAttributes->get($key) === null) { $attributes[$key] = $value; } } return new Attributes($attributes, $exemplarAttributes->getDroppedAttributesCount()); } }