Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
503 changes: 484 additions & 19 deletions src/OpenTelemetry/Metrics/AggregatorStore.cs

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions src/OpenTelemetry/Metrics/LookupData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// <copyright file="LookupData.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry 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.
// </copyright>

namespace OpenTelemetry.Metrics
{
internal class LookupData
{
public int Index;
public Tags SortedTags;
public Tags GivenTags;

public LookupData(int index, Tags sortedTags, Tags givenTags)
{
this.Index = index;
this.SortedTags = sortedTags;
this.GivenTags = givenTags;
}
}
}
41 changes: 40 additions & 1 deletion src/OpenTelemetry/Metrics/MetricPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ namespace OpenTelemetry.Metrics
/// </summary>
public struct MetricPoint
{
// Represents the number of update threads using this MetricPoint at any given point of time.
// If the value is equal to int.MinValue which is -2147483648, it means that this MetricPoint is available for reuse.
// We never increment the ReferenceCount for MetricPoint with no tags (index == 0) but we always decrement it (in the Update methods).
// This should be fine. ReferenceCount doesn't matter for MetricPoint with no tags as it is never reclaimed.
internal int ReferenceCount;

// When the AggregatorStore is reclaiming MetricPoints, this serves the purpose of validating the a given thread is using the right
// MetricPoint for update by checking it against what as added in the Dictionary. Also, when a thread finds out that the MetricPoint
// that its using is already reclaimed, this helps avoid sorting of the tags for adding a new Dictionary entry.
internal LookupData? LookupData;

// TODO: Ask spec to define a default value for this.
private const int DefaultSimpleReservoirPoolSize = 10;

Expand All @@ -49,17 +60,25 @@ internal MetricPoint(
KeyValuePair<string, object>[] tagKeysAndValues,
double[] histogramExplicitBounds,
int exponentialHistogramMaxSize,
int exponentialHistogramMaxScale)
int exponentialHistogramMaxScale,
LookupData? lookupData = null)
{
Debug.Assert(aggregatorStore != null, "AggregatorStore was null.");
Debug.Assert(histogramExplicitBounds != null, "Histogram explicit Bounds was null.");

if (aggregatorStore!.OutputDelta)
{
Debug.Assert(lookupData != null, "LookupData was null.");
}

this.aggType = aggType;
this.Tags = new ReadOnlyTagCollection(tagKeysAndValues);
this.runningValue = default;
this.snapshotValue = default;
this.deltaLastValue = default;
this.MetricPointStatus = MetricPointStatus.NoCollectPending;
this.ReferenceCount = 0;
this.LookupData = lookupData;

ExemplarReservoir? reservoir = null;
if (this.aggType == AggregationType.HistogramWithBuckets ||
Expand Down Expand Up @@ -420,6 +439,11 @@ internal void Update(long number)
// TODO: For Delta, this can be mitigated
// by ignoring Zero points
this.MetricPointStatus = MetricPointStatus.CollectPending;

if (this.aggregatorStore.OutputDelta)
{
Interlocked.Decrement(ref this.ReferenceCount);
}
}

internal void UpdateWithExemplar(long number, ReadOnlySpan<KeyValuePair<string, object>> tags, bool isSampled)
Expand Down Expand Up @@ -548,6 +572,11 @@ internal void UpdateWithExemplar(long number, ReadOnlySpan<KeyValuePair<string,
// TODO: For Delta, this can be mitigated
// by ignoring Zero points
this.MetricPointStatus = MetricPointStatus.CollectPending;

if (this.aggregatorStore.OutputDelta)
{
Interlocked.Decrement(ref this.ReferenceCount);
}
}

internal void Update(double number)
Expand Down Expand Up @@ -639,6 +668,11 @@ internal void Update(double number)
// TODO: For Delta, this can be mitigated
// by ignoring Zero points
this.MetricPointStatus = MetricPointStatus.CollectPending;

if (this.aggregatorStore.OutputDelta)
{
Interlocked.Decrement(ref this.ReferenceCount);
}
}

internal void UpdateWithExemplar(double number, ReadOnlySpan<KeyValuePair<string, object>> tags, bool isSampled)
Expand Down Expand Up @@ -775,6 +809,11 @@ internal void UpdateWithExemplar(double number, ReadOnlySpan<KeyValuePair<string
// TODO: For Delta, this can be mitigated
// by ignoring Zero points
this.MetricPointStatus = MetricPointStatus.CollectPending;

if (this.aggregatorStore.OutputDelta)
{
Interlocked.Decrement(ref this.ReferenceCount);
}
}

internal void TakeSnapshot(bool outputDelta)
Expand Down
2 changes: 2 additions & 0 deletions src/OpenTelemetry/Metrics/Tags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ namespace OpenTelemetry.Metrics
{
internal readonly struct Tags : IEquatable<Tags>
{
public static Tags EmptyTags = new Tags(Array.Empty<KeyValuePair<string, object>>());

private readonly int hashCode;

public Tags(KeyValuePair<string, object>[] keyValuePairs)
Expand Down
24 changes: 12 additions & 12 deletions test/Benchmarks/Metrics/MetricsBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@

| Method | AggregationTemporality | Mean | Error | StdDev | Allocated |
|-------------------------- |----------------------- |----------:|---------:|---------:|----------:|
| CounterHotPath | Cumulative | 17.06 ns | 0.113 ns | 0.094 ns | - |
| CounterWith1LabelsHotPath | Cumulative | 71.47 ns | 1.464 ns | 2.100 ns | - |
| CounterWith3LabelsHotPath | Cumulative | 162.04 ns | 2.469 ns | 2.188 ns | - |
| CounterWith5LabelsHotPath | Cumulative | 237.30 ns | 2.884 ns | 2.698 ns | - |
| CounterWith6LabelsHotPath | Cumulative | 269.41 ns | 4.087 ns | 3.623 ns | - |
| CounterWith7LabelsHotPath | Cumulative | 303.01 ns | 5.313 ns | 4.970 ns | - |
| CounterHotPath | Delta | 17.30 ns | 0.350 ns | 0.310 ns | - |
| CounterWith1LabelsHotPath | Delta | 70.96 ns | 0.608 ns | 0.539 ns | - |
| CounterWith3LabelsHotPath | Delta | 156.55 ns | 3.139 ns | 3.358 ns | - |
| CounterWith5LabelsHotPath | Delta | 247.14 ns | 4.703 ns | 5.598 ns | - |
| CounterWith6LabelsHotPath | Delta | 271.30 ns | 5.310 ns | 5.215 ns | - |
| CounterWith7LabelsHotPath | Delta | 309.02 ns | 5.934 ns | 5.828 ns | - |
| CounterHotPath | Cumulative | 21.62 ns | 0.201 ns | 0.188 ns | - |
| CounterWith1LabelsHotPath | Cumulative | 71.12 ns | 0.509 ns | 0.476 ns | - |
| CounterWith3LabelsHotPath | Cumulative | 156.46 ns | 1.512 ns | 1.340 ns | - |
| CounterWith5LabelsHotPath | Cumulative | 235.59 ns | 1.273 ns | 1.190 ns | - |
| CounterWith6LabelsHotPath | Cumulative | 264.38 ns | 2.671 ns | 2.368 ns | - |
| CounterWith7LabelsHotPath | Cumulative | 302.73 ns | 1.558 ns | 1.457 ns | - |
| CounterHotPath | Delta | 27.11 ns | 0.194 ns | 0.172 ns | - |
| CounterWith1LabelsHotPath | Delta | 90.23 ns | 0.270 ns | 0.225 ns | - |
| CounterWith3LabelsHotPath | Delta | 165.63 ns | 0.671 ns | 0.524 ns | - |
| CounterWith5LabelsHotPath | Delta | 254.29 ns | 0.897 ns | 0.795 ns | - |
| CounterWith6LabelsHotPath | Delta | 281.36 ns | 1.066 ns | 0.945 ns | - |
| CounterWith7LabelsHotPath | Delta | 316.55 ns | 3.161 ns | 2.957 ns | - |
*/

namespace Benchmarks.Metrics
Expand Down
Loading