Browse Source

More tests for MemoryGroup.Allocate()

pull/1109/head
Anton Firszov 6 years ago
parent
commit
98e5ca7433
  1. 5
      src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs
  2. 33
      tests/ImageSharp.Tests/Memory/DiscontiguousBuffers/MemoryGroupTests.cs
  3. 67
      tests/ImageSharp.Tests/TestUtilities/TestMemoryAllocator.cs

5
src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs

@ -27,7 +27,10 @@ namespace SixLabors.ImageSharp.Memory
public bool IsValid { get; protected set; }
// bufferLengthAlignment == image.Width in row-major images
public static MemoryGroup<T> Allocate(MemoryAllocator allocator, long totalLength, int blockAlignment)
public static MemoryGroup<T> Allocate(MemoryAllocator allocator,
long totalLength,
int blockAlignment,
AllocationOptions allocationOptions = AllocationOptions.None)
{
long bufferCount = totalLength / allocator.GetBlockCapacity();

33
tests/ImageSharp.Tests/Memory/DiscontiguousBuffers/MemoryGroupTests.cs

@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
using Xunit;
@ -80,6 +81,36 @@ namespace SixLabors.ImageSharp.Tests.Memory.DiscontiguousBuffers
MemoryGroup<byte>.Allocate(this.memoryAllocator, 50, 43);
});
}
[Theory]
[InlineData(AllocationOptions.None)]
[InlineData(AllocationOptions.Clean)]
public void MemoryAllocator_IsUtilizedCorrectly(AllocationOptions allocationOptions)
{
this.memoryAllocator.BlockCapacity = 200;
HashSet<int> bufferHashes;
int expectedBlockCount = 5;
using (var g = MemoryGroup<short>.Allocate(this.memoryAllocator, 500, 100, allocationOptions))
{
IReadOnlyList<TestMemoryAllocator.AllocationRequest> allocationLog = this.memoryAllocator.AllocationLog;
Assert.Equal(expectedBlockCount, allocationLog.Count);
bufferHashes = allocationLog.Select(l => l.HashCodeOfBuffer).ToHashSet();
Assert.Equal(expectedBlockCount, bufferHashes.Count);
Assert.Equal(0, this.memoryAllocator.ReturnLog.Count);
for (int i = 0; i < expectedBlockCount; i++)
{
Assert.Equal(allocationOptions, allocationLog[i].AllocationOptions);
Assert.Equal(100, allocationLog[i].Length);
Assert.Equal(200, allocationLog[i].LengthInBytes);
}
}
Assert.Equal(expectedBlockCount, this.memoryAllocator.ReturnLog.Count);
Assert.True(bufferHashes.SetEquals(this.memoryAllocator.ReturnLog.Select(l => l.HashCodeOfBuffer)));
}
}

67
tests/ImageSharp.Tests/TestUtilities/TestMemoryAllocator.cs

@ -13,7 +13,8 @@ namespace SixLabors.ImageSharp.Tests.Memory
{
internal class TestMemoryAllocator : MemoryAllocator
{
private List<AllocationRequest> allocationLog = new List<AllocationRequest>();
private readonly List<AllocationRequest> allocationLog = new List<AllocationRequest>();
private readonly List<ReturnRequest> returnLog = new List<ReturnRequest>();
public TestMemoryAllocator(byte dirtyValue = 42)
{
@ -27,27 +28,29 @@ namespace SixLabors.ImageSharp.Tests.Memory
public int BlockCapacity { get; set; } = int.MaxValue;
public IList<AllocationRequest> AllocationLog => this.allocationLog;
public IReadOnlyList<AllocationRequest> AllocationLog => this.allocationLog;
public IReadOnlyList<ReturnRequest> ReturnLog => this.returnLog;
protected internal override int GetBlockCapacity() => this.BlockCapacity;
public override IMemoryOwner<T> Allocate<T>(int length, AllocationOptions options = AllocationOptions.None)
{
T[] array = this.AllocateArray<T>(length, options);
return new BasicArrayBuffer<T>(array, length);
return new BasicArrayBuffer<T>(array, length, this);
}
public override IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options = AllocationOptions.None)
{
byte[] array = this.AllocateArray<byte>(length, options);
return new ManagedByteBuffer(array);
return new ManagedByteBuffer(array, this);
}
private T[] AllocateArray<T>(int length, AllocationOptions options)
where T : struct
{
this.allocationLog.Add(AllocationRequest.Create<T>(options, length));
var array = new T[length + 42];
this.allocationLog.Add(AllocationRequest.Create<T>(options, length, array));
if (options == AllocationOptions.None)
{
@ -58,25 +61,32 @@ namespace SixLabors.ImageSharp.Tests.Memory
return array;
}
private void Return<T>(BasicArrayBuffer<T> buffer)
where T : struct
{
this.returnLog.Add(new ReturnRequest(buffer.Array.GetHashCode()));
}
public struct AllocationRequest
{
private AllocationRequest(Type elementType, AllocationOptions allocationOptions, int length, int lengthInBytes)
private AllocationRequest(Type elementType, AllocationOptions allocationOptions, int length, int lengthInBytes, int hashCodeOfBuffer)
{
this.ElementType = elementType;
this.AllocationOptions = allocationOptions;
this.Length = length;
this.LengthInBytes = lengthInBytes;
this.HashCodeOfBuffer = hashCodeOfBuffer;
if (elementType == typeof(Vector4))
{
}
}
public static AllocationRequest Create<T>(AllocationOptions allocationOptions, int length)
public static AllocationRequest Create<T>(AllocationOptions allocationOptions, int length, T[] buffer)
{
Type type = typeof(T);
int elementSize = Marshal.SizeOf(type);
return new AllocationRequest(type, allocationOptions, length, length * elementSize);
return new AllocationRequest(type, allocationOptions, length, length * elementSize, buffer.GetHashCode());
}
public Type ElementType { get; }
@ -86,6 +96,18 @@ namespace SixLabors.ImageSharp.Tests.Memory
public int Length { get; }
public int LengthInBytes { get; }
public int HashCodeOfBuffer { get; }
}
public struct ReturnRequest
{
public ReturnRequest(int hashCodeOfBuffer)
{
this.HashCodeOfBuffer = hashCodeOfBuffer;
}
public int HashCodeOfBuffer { get; }
}
/// <summary>
@ -94,36 +116,29 @@ namespace SixLabors.ImageSharp.Tests.Memory
private class BasicArrayBuffer<T> : MemoryManager<T>
where T : struct
{
private readonly TestMemoryAllocator allocator;
private GCHandle pinHandle;
/// <summary>
/// Initializes a new instance of the <see cref="BasicArrayBuffer{T}"/> class
/// </summary>
/// <param name="array">The array</param>
/// <param name="length">The length of the buffer</param>
public BasicArrayBuffer(T[] array, int length)
public BasicArrayBuffer(T[] array, int length, TestMemoryAllocator allocator)
{
this.allocator = allocator;
DebugGuard.MustBeLessThanOrEqualTo(length, array.Length, nameof(length));
this.Array = array;
this.Length = length;
}
/// <summary>
/// Initializes a new instance of the <see cref="BasicArrayBuffer{T}"/> class
/// </summary>
/// <param name="array">The array</param>
public BasicArrayBuffer(T[] array)
: this(array, array.Length)
public BasicArrayBuffer(T[] array, TestMemoryAllocator allocator)
: this(array, array.Length, allocator)
{
}
/// <summary>
/// Gets the array
/// Gets the array.
/// </summary>
public T[] Array { get; }
/// <summary>
/// Gets the length
/// Gets the length.
/// </summary>
public int Length { get; }
@ -149,13 +164,17 @@ namespace SixLabors.ImageSharp.Tests.Memory
/// <inheritdoc />
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.allocator.Return(this);
}
}
}
private class ManagedByteBuffer : BasicArrayBuffer<byte>, IManagedByteBuffer
{
public ManagedByteBuffer(byte[] array)
: base(array)
public ManagedByteBuffer(byte[] array, TestMemoryAllocator allocator)
: base(array, allocator)
{
}
}

Loading…
Cancel
Save