mirror of https://github.com/SixLabors/ImageSharp
13 changed files with 154 additions and 43 deletions
@ -0,0 +1,21 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace SixLabors.ImageSharp.Memory |
|||
{ |
|||
/// <summary>
|
|||
/// Represents discontiguous group of multiple uniformly-sized memory segments.
|
|||
/// The last segment can be smaller than the preceding ones.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The element type.</typeparam>
|
|||
public interface IMemoryGroup<T> : IReadOnlyList<Memory<T>> |
|||
where T : struct |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the number of elements per contiguous sub-block.
|
|||
/// </summary>
|
|||
public int BlockSize { get; } |
|||
|
|||
bool IsValid { get; } |
|||
} |
|||
} |
|||
@ -1,6 +1,6 @@ |
|||
using System; |
|||
|
|||
namespace SixLabors.ImageSharp.Memory.DiscontinuousProto |
|||
namespace SixLabors.ImageSharp.Memory |
|||
{ |
|||
public class InvalidMemoryOperationException : InvalidOperationException |
|||
{ |
|||
@ -1,12 +1,12 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace SixLabors.ImageSharp.Memory.DiscontinuousProto |
|||
namespace SixLabors.ImageSharp.Memory |
|||
{ |
|||
internal abstract partial class UniformMemoryGroup<T> |
|||
internal abstract partial class MemoryGroup<T> |
|||
{ |
|||
// Analogous to the "consumed" variant of MemorySource
|
|||
private class Consumed : UniformMemoryGroup<T> |
|||
private class Consumed : MemoryGroup<T> |
|||
{ |
|||
private readonly ReadOnlyMemory<Memory<T>> source; |
|||
|
|||
@ -1,15 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace SixLabors.ImageSharp.Memory.DiscontinuousProto |
|||
{ |
|||
/// <summary>
|
|||
/// Represents discontinuous group of multiple uniformly-sized memory segments.
|
|||
/// The last segment can be smaller than the preceding ones.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The element type.</typeparam>
|
|||
public interface IUniformMemoryGroup<T> : IReadOnlyList<Memory<T>> where T : struct |
|||
{ |
|||
bool IsValid { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,96 @@ |
|||
using System.Linq; |
|||
using System.Runtime.InteropServices; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Memory.DiscontiguousBuffers |
|||
{ |
|||
public class MemoryGroupTests |
|||
{ |
|||
public class Allocate |
|||
{ |
|||
private readonly TestMemoryAllocator memoryAllocator = new TestMemoryAllocator(); |
|||
|
|||
#pragma warning disable SA1509
|
|||
public static TheoryData<object, int, int, long, int, int, int> AllocateData = |
|||
new TheoryData<object, int, int, long, int, int, int>() |
|||
{ |
|||
{ default(S5), 22, 4, 4, 1, 4, 4 }, |
|||
{ default(S5), 22, 4, 7, 2, 4, 3 }, |
|||
{ default(S5), 22, 4, 8, 2, 4, 4 }, |
|||
{ default(S5), 22, 4, 21, 5, 4, 1 }, |
|||
{ default(S5), 22, 4, 0, 0, -1, -1 }, |
|||
|
|||
{ default(S4), 50, 12, 12, 1, 12, 12 }, |
|||
{ default(S4), 50, 7, 12, 2, 7, 5 }, |
|||
{ default(S4), 50, 6, 12, 2, 6, 6 }, |
|||
{ default(S4), 50, 5, 12, 2, 10, 2 }, |
|||
{ default(S4), 50, 4, 12, 1, 12, 12 }, |
|||
{ default(S4), 50, 3, 12, 1, 12, 12 }, |
|||
{ default(S4), 50, 2, 12, 1, 12, 12 }, |
|||
{ default(S4), 50, 1, 12, 1, 12, 12 }, |
|||
|
|||
{ default(S4), 50, 12, 13, 2, 12, 1 }, |
|||
{ default(S4), 50, 7, 21, 3, 7, 7 }, |
|||
{ default(S4), 50, 7, 23, 3, 7, 2 }, |
|||
|
|||
{ default(byte), 1000, 512, 2047, 4, 512, 511 } |
|||
}; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(AllocateData))] |
|||
public void CreatesBlocksOfCorrectSizes<T>( |
|||
T dummy, |
|||
int blockCapacity, |
|||
int blockAlignment, |
|||
long totalLength, |
|||
int expectedNumberOfBlocks, |
|||
int expectedBlockSize, |
|||
int expectedSizeOfLastBlock) |
|||
where T : struct |
|||
{ |
|||
this.memoryAllocator.BlockCapacity = blockCapacity; |
|||
|
|||
// Act:
|
|||
using var g = MemoryGroup<T>.Allocate(this.memoryAllocator, totalLength, blockAlignment); |
|||
|
|||
// Assert:
|
|||
Assert.Equal(expectedNumberOfBlocks, g.Count); |
|||
Assert.Equal(expectedBlockSize, g.BlockSize); |
|||
if (g.Count == 0) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
for (int i = 0; i < g.Count - 1; i++) |
|||
{ |
|||
Assert.Equal(g[i].Length, expectedBlockSize); |
|||
} |
|||
|
|||
Assert.Equal(g.Last().Length, expectedSizeOfLastBlock); |
|||
} |
|||
|
|||
[Fact] |
|||
public void WhenBlockAlignmentIsOverCapacity_Throws_InvalidMemoryOperationException() |
|||
{ |
|||
this.memoryAllocator.BlockCapacity = 42; |
|||
|
|||
Assert.Throws<InvalidMemoryOperationException>(() => |
|||
{ |
|||
MemoryGroup<byte>.Allocate(this.memoryAllocator, 50, 43); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
|
|||
[StructLayout(LayoutKind.Sequential, Size = 5)] |
|||
private struct S5 |
|||
{ |
|||
} |
|||
|
|||
[StructLayout(LayoutKind.Sequential, Size = 4)] |
|||
private struct S4 |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue