Skip to content

Commit

Permalink
calculate scale reduction
Browse files Browse the repository at this point in the history
  • Loading branch information
reyang committed Jul 22, 2022
1 parent 906be33 commit 91d7404
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 30 deletions.
37 changes: 28 additions & 9 deletions src/OpenTelemetry/Metrics/CircularBufferBuckets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,44 +64,63 @@ public long this[int index]
/// </summary>
/// <param name="index">The index of the bucket.</param>
/// <returns>
/// Returns <c>true</c> if the increment attempt succeeded;
/// <c>false</c> if the underlying buffer is running out of capacity.
/// Returns <c>0</c> if the increment attempt succeeded;
/// Returns a positive integer <c>Math.Ceiling(log_2(X))</c> if the
/// underlying buffer is running out of capacity, and the buffer has to
/// increase to <c>X * Capacity</c> at minimum.
/// </returns>
/// <remarks>
/// The "index" value can be positive, zero or negative.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryIncrement(int index)
public int TryIncrement(int index)
{
var capacity = this.Capacity;

if (this.trait == null)
{
this.trait = new long[this.Capacity];
this.trait = new long[capacity];

this.begin = index;
this.end = index;
}
else if (index > this.end)
{
if (index - this.begin >= this.Capacity)
var diff = index - this.begin;
if (diff >= capacity)
{
return false;
return CalculateScaleReduction(diff + 1, capacity);
}

this.end = index;
}
else if (index < this.begin)
{
if (this.end - index >= this.Capacity)
var diff = this.end - index;
if (diff >= this.Capacity)
{
return false;
return CalculateScaleReduction(diff + 1, capacity);
}

this.begin = index;
}

this.trait[this.ModuloIndex(index)] += 1;

return true;
return 0;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
int CalculateScaleReduction(int size, int capacity)
{
var shift = MathHelper.LeadingZero32(capacity) - MathHelper.LeadingZero32(size);

if (size > (capacity << shift))
{
shift++;
}

return shift;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
48 changes: 27 additions & 21 deletions test/OpenTelemetry.Tests/Metrics/CircularBufferBucketsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,29 @@ public void BasicInsertions()
Assert.Equal(5, buckets.Capacity);
Assert.Equal(0, buckets.Size);

Assert.True(buckets.TryIncrement(0));
Assert.Equal(0, buckets.TryIncrement(0));
Assert.Equal(1, buckets.Size);

Assert.True(buckets.TryIncrement(1));
Assert.Equal(0, buckets.TryIncrement(1));
Assert.Equal(2, buckets.Size);

Assert.True(buckets.TryIncrement(3));
Assert.Equal(0, buckets.TryIncrement(3));
Assert.Equal(4, buckets.Size);

Assert.True(buckets.TryIncrement(4));
Assert.Equal(0, buckets.TryIncrement(4));
Assert.Equal(5, buckets.Size);

Assert.True(buckets.TryIncrement(2));
Assert.Equal(0, buckets.TryIncrement(2));
Assert.Equal(5, buckets.Size);

Assert.False(buckets.TryIncrement(5));
Assert.False(buckets.TryIncrement(-1));
Assert.Equal(1, buckets.TryIncrement(9));
Assert.Equal(1, buckets.TryIncrement(5));
Assert.Equal(1, buckets.TryIncrement(-1));
Assert.Equal(2, buckets.TryIncrement(10));
Assert.Equal(2, buckets.TryIncrement(19));
Assert.Equal(3, buckets.TryIncrement(20));
Assert.Equal(3, buckets.TryIncrement(39));
Assert.Equal(4, buckets.TryIncrement(40));
Assert.Equal(5, buckets.Size);
}

Expand All @@ -61,29 +67,29 @@ public void PositiveInsertions()
{
var buckets = new CircularBufferBuckets(5);

Assert.True(buckets.TryIncrement(102));
Assert.True(buckets.TryIncrement(103));
Assert.True(buckets.TryIncrement(101));
Assert.True(buckets.TryIncrement(100));
Assert.True(buckets.TryIncrement(104));
Assert.Equal(0, buckets.TryIncrement(102));
Assert.Equal(0, buckets.TryIncrement(103));
Assert.Equal(0, buckets.TryIncrement(101));
Assert.Equal(0, buckets.TryIncrement(100));
Assert.Equal(0, buckets.TryIncrement(104));

Assert.False(buckets.TryIncrement(99));
Assert.False(buckets.TryIncrement(105));
Assert.Equal(1, buckets.TryIncrement(99));
Assert.Equal(1, buckets.TryIncrement(105));
}

[Fact]
public void NegativeInsertions()
{
var buckets = new CircularBufferBuckets(5);

Assert.True(buckets.TryIncrement(2));
Assert.True(buckets.TryIncrement(0));
Assert.True(buckets.TryIncrement(-2));
Assert.True(buckets.TryIncrement(1));
Assert.True(buckets.TryIncrement(-1));
Assert.Equal(0, buckets.TryIncrement(2));
Assert.Equal(0, buckets.TryIncrement(0));
Assert.Equal(0, buckets.TryIncrement(-2));
Assert.Equal(0, buckets.TryIncrement(1));
Assert.Equal(0, buckets.TryIncrement(-1));

Assert.False(buckets.TryIncrement(3));
Assert.False(buckets.TryIncrement(-3));
Assert.Equal(1, buckets.TryIncrement(3));
Assert.Equal(1, buckets.TryIncrement(-3));
}

[Fact]
Expand Down

0 comments on commit 91d7404

Please sign in to comment.