Skip to content

Commit

Permalink
Batches size now affects sending size accurately. Use extensions to h…
Browse files Browse the repository at this point in the history
…elp test this
  • Loading branch information
adamhathcock committed Feb 17, 2025
1 parent e5a0915 commit b72d91c
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 12 deletions.
29 changes: 29 additions & 0 deletions src/Speckle.Sdk.Dependencies/Serialization/BatchExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Buffers;

namespace Speckle.Sdk.Serialisation.V2.Send;

public static class BatchExtensions
{
public static void TrimBatch<T>(ref IMemoryOwner<T> batch, bool isVerifiedFull)
where T : IHasSize
{
if (!isVerifiedFull)
{
((Batch<T>)batch).TrimExcess();
}
}

public static void AddBatchItem<T>(this IMemoryOwner<T> batch, T item)
where T : IHasSize => ((Batch<T>)batch).Add(item);

public static int GetBatchSize<T>(this IMemoryOwner<T> batch, int maxBatchSize) where T : IHasSize
{
var currentSize = ((Batch<T>)batch).Size;
if (currentSize > maxBatchSize)
{
return maxBatchSize;
}

return currentSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,22 @@ public interface IHasSize
int Size { get; }
}

public class SizeBatchingChannelReader<T>(
public sealed class SizeBatchingChannelReader<T>(
ChannelReader<T> source,
int batchSize,
bool singleReader,
bool syncCont = false
) : BatchingChannelReader<T, IMemoryOwner<T>>(x => new Batch<T>(), source, batchSize, singleReader, syncCont)
bool syncCont = false)
: BatchingChannelReader<T, IMemoryOwner<T>>(x => new Batch<T>(), source, batchSize, singleReader, syncCont)
where T : IHasSize
{
protected override IMemoryOwner<T> CreateBatch(int capacity) => new Batch<T>();
private readonly int _batchSize = batchSize;

protected override IMemoryOwner<T> CreateBatch(int capacity) => new Batch<T>();

protected override void TrimBatch(ref IMemoryOwner<T> batch, bool isVerifiedFull)
{
if (!isVerifiedFull)
{
((Batch<T>)batch).TrimExcess();
}
}
=> BatchExtensions.TrimBatch(ref batch, isVerifiedFull);

protected override void AddBatchItem(IMemoryOwner<T> batch, T item) => ((Batch<T>)batch).Add(item);
protected override void AddBatchItem(IMemoryOwner<T> batch, T item) => batch.AddBatchItem( item);

protected override int GetBatchSize(IMemoryOwner<T> batch) => ((Batch<T>)batch).Size;
protected override int GetBatchSize(IMemoryOwner<T> batch)=> batch.GetBatchSize( _batchSize);
}
65 changes: 65 additions & 0 deletions tests/Speckle.Sdk.Serialization.Tests/BatchTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using FluentAssertions;
using Speckle.Sdk.Serialisation.V2.Send;

namespace Speckle.Sdk.Serialization.Tests;

public class BatchTests
{

/*** from BatchingChannelReader.cs **
bool full = GetBatchSize(c) == _batchSize;
while (!full && source.TryRead(out item))
{
AddBatchItem(c, item);
full = GetBatchSize(c) == _batchSize;
}*/

public class TestBatchItem : IHasSize
{
public int Size { get; set; }
}

[Fact]
public void Basics()
{
using var batch = new Batch<TestBatchItem>();
batch.Add(new TestBatchItem { Size = 2 });
batch.Size.Should().Be(2);
batch.Add(new TestBatchItem { Size = 2 });
batch.Size.Should().Be(4);
batch.Add(new TestBatchItem { Size = 2 });
batch.Size.Should().Be(6);

batch.TrimExcess();
batch.Size.Should().Be(6);
batch.Items.Count.Should().Be(3);
}

[Fact]
public void Large_Message_Problem_1()
{
const int MAX_BATCH_SIZE = 5;


using var batch = new Batch<TestBatchItem>();
batch.AddBatchItem(new TestBatchItem { Size = 2 });
bool full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE;
full.Should().BeFalse();
batch.AddBatchItem(new TestBatchItem { Size = 2 });
full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE;
full.Should().BeFalse();
batch.AddBatchItem(new TestBatchItem { Size = 2 });
full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE;
full.Should().BeTrue();
}

[Fact]
public void Large_Message_Problem_2()
{
const int MAX_BATCH_SIZE = 5;
using var batch = new Batch<TestBatchItem>();
batch.AddBatchItem(new TestBatchItem { Size = 6 });
bool full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE;
full.Should().BeTrue();
}
}

0 comments on commit b72d91c

Please sign in to comment.