Exponential Bucket Histogram - part 4 (#3477)

* cover integer overflow

* seal

* static
This commit is contained in:
Reiley Yang 2022-07-22 16:59:52 -07:00 committed by GitHub
parent bfabe9bc26
commit 720cbdd2f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 5 deletions

View File

@ -22,7 +22,7 @@ namespace OpenTelemetry.Metrics;
/// <summary>
/// A histogram buckets implementation based on circular buffer.
/// </summary>
internal class CircularBufferBuckets
internal sealed class CircularBufferBuckets
{
private long[] trait;
private int begin = 0;
@ -87,7 +87,8 @@ internal class CircularBufferBuckets
else if (index > this.end)
{
var diff = index - this.begin;
if (diff >= capacity)
if (diff >= capacity || diff < 0)
{
return CalculateScaleReduction(diff + 1, capacity);
}
@ -97,7 +98,8 @@ internal class CircularBufferBuckets
else if (index < this.begin)
{
var diff = this.end - index;
if (diff >= this.Capacity)
if (diff >= this.Capacity || diff < 0)
{
return CalculateScaleReduction(diff + 1, capacity);
}
@ -110,9 +112,14 @@ internal class CircularBufferBuckets
return 0;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
int CalculateScaleReduction(int size, int capacity)
static int CalculateScaleReduction(int size, int capacity)
{
var shift = MathHelper.LeadingZero32(capacity) - MathHelper.LeadingZero32(size);
var shift = MathHelper.LeadingZero32(capacity);
if (size > 0)
{
shift -= MathHelper.LeadingZero32(size);
}
if (size > (capacity << shift))
{

View File

@ -92,6 +92,19 @@ public class CircularBufferBucketsTest
Assert.Equal(1, buckets.TryIncrement(-3));
}
[Fact]
public void IntegerOverflow()
{
var buckets = new CircularBufferBuckets(1);
Assert.Equal(0, buckets.TryIncrement(int.MaxValue));
Assert.Equal(31, buckets.TryIncrement(1));
Assert.Equal(31, buckets.TryIncrement(0));
Assert.Equal(32, buckets.TryIncrement(-1));
Assert.Equal(32, buckets.TryIncrement(int.MinValue + 1));
Assert.Equal(32, buckets.TryIncrement(int.MinValue));
}
[Fact]
public void IndexOperations()
{