Skip to content

Commit

Permalink
CopyTo for memory and span
Browse files Browse the repository at this point in the history
  • Loading branch information
k-wojcik committed Sep 30, 2024
1 parent d574652 commit e4f685d
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/Roaring.Net/CRoaring/FrozenRoaring32Bitmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,20 @@ public bool ContainsBulk(BulkContext context, uint value)
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="buffer"/> size is too small to write the bitmap.</exception>
public void CopyTo(uint[] buffer) => _bitmap.CopyTo(buffer);

/// <summary>
/// Writes current bitmap to the <paramref name="buffer"/> given in the parameter.
/// </summary>
/// <param name="buffer">The <see cref="Memory{T}"/> in which the bitmap will be written.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="buffer"/> size is too small to write the bitmap.</exception>
public void CopyTo(Memory<uint> buffer) => _bitmap.CopyTo(buffer);

/// <summary>
/// Writes current bitmap to the <paramref name="buffer"/> given in the parameter.
/// </summary>
/// <param name="buffer">The <see cref="Span{T}"/> in which the bitmap will be written.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="buffer"/> size is too small to write the bitmap.</exception>
public void CopyTo(Span<uint> buffer) => _bitmap.CopyTo(buffer);

/// <summary>
/// Gets enumerator that returns the values contained in the bitmap.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions src/Roaring.Net/CRoaring/IReadOnlyRoaring32Bitmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ internal interface IReadOnlyRoaring32Bitmap : IDisposable

void CopyTo(uint[] buffer);

void CopyTo(Memory<uint> buffer);

void CopyTo(Span<uint> buffer);

IEnumerable<uint> Values { get; }

uint[] ToArray();
Expand Down
8 changes: 8 additions & 0 deletions src/Roaring.Net/CRoaring/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,14 @@ internal static unsafe partial class NativeMethods
public static extern void roaring_bitmap_to_uint32_array(IntPtr bitmap, [Out] uint[] values);
#endif

#if NET7_0_OR_GREATER
[LibraryImport("roaring", EntryPoint = "roaring_bitmap_to_uint32_array")]
public static partial void roaring_bitmap_to_uint32_array(IntPtr bitmap, Span<uint> values);
#else
[DllImport("roaring")]
public static extern void roaring_bitmap_to_uint32_array(IntPtr bitmap, Span<uint> values);
#endif

#if NET7_0_OR_GREATER
[LibraryImport("roaring", EntryPoint = "roaring_bitmap_serialize")]
public static partial nuint roaring_bitmap_serialize(IntPtr bitmap, [Out] byte[] buffer);
Expand Down
22 changes: 22 additions & 0 deletions src/Roaring.Net/CRoaring/Roaring32Bitmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,28 @@ public void CopyTo(uint[] buffer)
NativeMethods.roaring_bitmap_to_uint32_array(Pointer, buffer);
}

/// <summary>
/// Writes current bitmap to the <paramref name="buffer"/> given in the parameter.
/// </summary>
/// <param name="buffer">The <see cref="Memory{T}"/> in which the bitmap will be written.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="buffer"/> size is too small to write the bitmap.</exception>
public void CopyTo(Memory<uint> buffer) => CopyTo(buffer.Span);

/// <summary>
/// Writes current bitmap to the <paramref name="buffer"/> given in the parameter.
/// </summary>
/// <param name="buffer">The <see cref="Span{T}"/> in which the bitmap will be written.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="buffer"/> size is too small to write the bitmap.</exception>
public void CopyTo(Span<uint> buffer)
{
if ((ulong)buffer.Length < Count)
{
throw new ArgumentOutOfRangeException(nameof(buffer), buffer.Length, ExceptionMessages.BufferSizeIsTooSmall);
}

NativeMethods.roaring_bitmap_to_uint32_array(Pointer, buffer);
}

/// <summary>
/// Gets enumerator that returns the values contained in the bitmap.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void ToArray_Always_ReturnsArrayWithExpectedValues(uint[] expected, IRoar
}
}

public class CopyTo
public class CopyToArray
{
[Theory]
[InlineTestObject(new uint[] { })]
Expand Down Expand Up @@ -91,6 +91,140 @@ public void CopyTo_OutputCollectionSizeGreaterThanNumberOfValues_ReturnsFilledCo
}
}

public class CopyToMemory
{
[Theory]
[InlineTestObject(new uint[] { })]
[InlineTestObject(new uint[] { uint.MaxValue })]
[InlineTestObject(new uint[] { 0, 1, 2, 3, 4 })]
public void CopyTo_OutputCollectionSizeEqualToNumberOfValues_ReturnsFilledCollection(uint[] expected, IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
using IRoaring32BitmapTestObject testObject = factory.GetFromValues(expected);
uint[] actual = new uint[expected.Length];

// Act
testObject.ReadOnlyBitmap.CopyTo(actual.AsMemory());

// Assert
Assert.Equal(expected, actual);
}

[Theory]
[InlineTestObject]
public void CopyTo_OutputCollectionIsEmptyWhenBitmapHasValues_ThrowsArgumentOutOfRangeException(IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
using IRoaring32BitmapTestObject testObject = factory.GetDefault();
uint[] actual = [];

// Act && Assert
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
testObject.ReadOnlyBitmap.CopyTo(actual.AsMemory());
});
}

[Theory]
[InlineTestObject]
public void CopyTo_OutputCollectionSizeLowerThanNumberOfValues_ThrowsArgumentOutOfRangeException(IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
var input = new uint[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
using IRoaring32BitmapTestObject testObject = factory.GetFromValues(input);

// Act && Assert
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
testObject.ReadOnlyBitmap.CopyTo(new uint[input.Length - 5].AsMemory());
});
}

[Theory]
[InlineTestObject]
public void CopyTo_OutputCollectionSizeGreaterThanNumberOfValues_ReturnsFilledCollectionFromBeginning(IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
var expected = new uint[] { 0, 1, 2, 3, 4, 0, 0, 0, 0, 0 };
var input = expected[..5];
using IRoaring32BitmapTestObject testObject = factory.GetFromValues(input);
uint[] actual = new uint[input.Length + 5];

// Act
testObject.ReadOnlyBitmap.CopyTo(actual.AsMemory());

// Assert
Assert.Equal(expected, actual);
}
}

public class CopyToSpan
{
[Theory]
[InlineTestObject(new uint[] { })]
[InlineTestObject(new uint[] { uint.MaxValue })]
[InlineTestObject(new uint[] { 0, 1, 2, 3, 4 })]
public void CopyTo_OutputCollectionSizeEqualToNumberOfValues_ReturnsFilledCollection(uint[] expected, IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
using IRoaring32BitmapTestObject testObject = factory.GetFromValues(expected);
uint[] actual = new uint[expected.Length];

// Act
testObject.ReadOnlyBitmap.CopyTo(actual.AsSpan());

// Assert
Assert.Equal(expected, actual);
}

[Theory]
[InlineTestObject]
public void CopyTo_OutputCollectionIsEmptyWhenBitmapHasValues_ThrowsArgumentOutOfRangeException(IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
using IRoaring32BitmapTestObject testObject = factory.GetDefault();
uint[] actual = [];

// Act && Assert
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
testObject.ReadOnlyBitmap.CopyTo(actual.AsSpan());
});
}

[Theory]
[InlineTestObject]
public void CopyTo_OutputCollectionSizeLowerThanNumberOfValues_ThrowsArgumentOutOfRangeException(IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
var input = new uint[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
using IRoaring32BitmapTestObject testObject = factory.GetFromValues(input);

// Act && Assert
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
testObject.ReadOnlyBitmap.CopyTo(new uint[input.Length - 5].AsSpan());
});
}

[Theory]
[InlineTestObject]
public void CopyTo_OutputCollectionSizeGreaterThanNumberOfValues_ReturnsFilledCollectionFromBeginning(IRoaring32BitmapTestObjectFactory factory)
{
// Arrange
var expected = new uint[] { 0, 1, 2, 3, 4, 0, 0, 0, 0, 0 };
var input = expected[..5];
using IRoaring32BitmapTestObject testObject = factory.GetFromValues(input);
uint[] actual = new uint[input.Length + 5];

// Act
testObject.ReadOnlyBitmap.CopyTo(actual.AsSpan());

// Assert
Assert.Equal(expected, actual);
}
}

public class Take
{
[Theory]
Expand Down

0 comments on commit e4f685d

Please sign in to comment.