Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exponential Bucket Histogram - part 9 #3553

Merged
merged 9 commits into from
Aug 5, 2022
Merged
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
Prev Previous commit
Next Next commit
support older runtime < net6.0
reyang committed Aug 5, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 7711a87aa0b34ca2cbc14a67784b7ed1f372a1cc
16 changes: 7 additions & 9 deletions src/OpenTelemetry/Metrics/ExponentialBucketHistogram.cs
Original file line number Diff line number Diff line change
@@ -14,8 +14,6 @@
// limitations under the License.
// </copyright>

#if NET6_0_OR_GREATER

using System;
using System.Diagnostics;
using OpenTelemetry.Internal;
@@ -30,8 +28,6 @@ namespace OpenTelemetry.Metrics;
/// </summary>
internal class ExponentialBucketHistogram
{
private static readonly double Log2E = Math.Log2(Math.E); // 1 / Math.Log(2)

private int scale;
private double scalingFactor; // 2 ^ scale / log(2)

@@ -107,13 +103,17 @@ internal int Scale
{
get => this.scale;

private set
set
{
this.scale = value;
this.scalingFactor = Math.ScaleB(Log2E, value);

// A subset of Math.ScaleB(Math.Log2(Math.E), value)
this.scalingFactor = BitConverter.Int64BitsToDouble(0x71547652B82FEL | ((0x3FFL + value) << 52 /* fraction width */));
}
}

internal double ScalingFactor => this.scalingFactor;

internal CircularBufferBuckets PositiveBuckets { get; }

internal long ZeroCount { get; private set; }
@@ -135,7 +135,7 @@ public int MapToIndex(double value)
{
Debug.Assert(MathHelper.IsFinite(value), "IEEE-754 +Inf, -Inf and NaN should be filtered out before calling this method.");
Debug.Assert(value != 0, "IEEE-754 zero values should be handled by ZeroCount.");
Debug.Assert(!double.IsNegative(value), "IEEE-754 negative values should be normalized before calling this method.");
Debug.Assert(value > 0, "IEEE-754 negative values should be normalized before calling this method.");

var bits = BitConverter.DoubleToInt64Bits(value);
var fraction = bits & 0xFFFFFFFFFFFFFL /* fraction mask */;
@@ -202,5 +202,3 @@ public void Record(double value)
Debug.Assert(n == 0, "Increment should always succeed after scale down.");
}
}

#endif
106 changes: 102 additions & 4 deletions test/OpenTelemetry.Tests/Metrics/ExponentialBucketHistogramTest.cs
Original file line number Diff line number Diff line change
@@ -14,8 +14,6 @@
// limitations under the License.
// </copyright>

#if NET6_0_OR_GREATER

using System;
using OpenTelemetry.Tests;
using Xunit;
@@ -24,6 +22,108 @@ namespace OpenTelemetry.Metrics.Tests;

public class ExponentialBucketHistogramTest
{
[Fact]
public void ScalingFactorCalculation()
{
var histogram = new ExponentialBucketHistogram();

histogram.Scale = 20;
Assert.Equal("0 10000010011 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 19;
Assert.Equal("0 10000010010 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 18;
Assert.Equal("0 10000010001 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 17;
Assert.Equal("0 10000010000 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 16;
Assert.Equal("0 10000001111 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 15;
Assert.Equal("0 10000001110 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 14;
Assert.Equal("0 10000001101 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 13;
Assert.Equal("0 10000001100 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 12;
Assert.Equal("0 10000001011 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 11;
Assert.Equal("0 10000001010 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 10;
Assert.Equal("0 10000001001 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 9;
Assert.Equal("0 10000001000 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 8;
Assert.Equal("0 10000000111 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 7;
Assert.Equal("0 10000000110 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 6;
Assert.Equal("0 10000000101 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 5;
Assert.Equal("0 10000000100 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 4;
Assert.Equal("0 10000000011 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 3;
Assert.Equal("0 10000000010 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 2;
Assert.Equal("0 10000000001 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 1;
Assert.Equal("0 10000000000 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = 0;
Assert.Equal("0 01111111111 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -1;
Assert.Equal("0 01111111110 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -2;
Assert.Equal("0 01111111101 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -3;
Assert.Equal("0 01111111100 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -4;
Assert.Equal("0 01111111011 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -5;
Assert.Equal("0 01111111010 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -6;
Assert.Equal("0 01111111001 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -7;
Assert.Equal("0 01111111000 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -8;
Assert.Equal("0 01111110111 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -9;
Assert.Equal("0 01111110110 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -10;
Assert.Equal("0 01111110101 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());

histogram.Scale = -11;
Assert.Equal("0 01111110100 0111000101010100011101100101001010111000001011111110", IEEE754Double.FromDouble(histogram.ScalingFactor).ToString());
}

[Fact]
public void IndexLookupScale0()
{
@@ -368,5 +468,3 @@ public void ZeroHandling()
Assert.Equal(2, histogram.ZeroCount);
}
}

#endif
2 changes: 1 addition & 1 deletion test/OpenTelemetry.Tests/Shared/IEEE754Double.cs
Original file line number Diff line number Diff line change
@@ -98,6 +98,6 @@ public override string ToString()

chars[index--] = (char)(bits & 0x01 | 0x30);

return $"{chars.ToString()} ({this.DoubleValue})";
return chars.ToString();
}
}