637 lines
22 KiB
C#
637 lines
22 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using UnmanagedMMU;
|
|
using UnmanagedMMU.Allocators;
|
|
using Xunit;
|
|
|
|
namespace UnmanagedMMUTests
|
|
{
|
|
|
|
/// <summary>
|
|
/// UnmanagedAllocator that will fail
|
|
/// </summary>
|
|
public sealed unsafe class FailingAllocator : IUnmanagedAllocator
|
|
{
|
|
private readonly int _failAfter;
|
|
private int _allocCount;
|
|
|
|
/// <summary>
|
|
/// Initializes a new <see cref="SegmentedPool"/> wich fails after <paramref name="failAfterNSegmentsAllocated"/> bytes has been allocated
|
|
/// </summary>
|
|
/// <param name="failAfterNSegmentsAllocated">Indicates the number of allocations that are allowed to succssed, more allocations after this will fail </param>
|
|
public FailingAllocator(int failAfterNSegmentsAllocated = 0)
|
|
{
|
|
// each segment has two unmanaged allocs!
|
|
_failAfter = 2 * failAfterNSegmentsAllocated;
|
|
}
|
|
|
|
public void* Alloc(nuint size)
|
|
{
|
|
_allocCount++;
|
|
if (_allocCount > _failAfter)
|
|
{
|
|
throw new OutOfMemoryException("The allocator has failed!");
|
|
}
|
|
return NativeMemory.Alloc(size);
|
|
}
|
|
|
|
public void Free(void* ptr)
|
|
{
|
|
NativeMemory.Free(ptr);
|
|
}
|
|
}
|
|
|
|
public class SegmentedPoolTests
|
|
{
|
|
|
|
#region TestData
|
|
|
|
public struct TestMyStruct
|
|
{
|
|
public int A;
|
|
public double B;
|
|
}
|
|
|
|
// Example enum
|
|
public enum TestMyEnum : int
|
|
{
|
|
First,
|
|
Second
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void AssertSpanIsNotEmptyAndHasNElements<T>(Span<T> span, int nElements) where T : unmanaged
|
|
{
|
|
Assert.False(span.IsEmpty);
|
|
Assert.Equal(nElements, span.Length);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that an ArgumentException is raised if zero is given for SegmentSize
|
|
/// </summary>
|
|
[Fact]
|
|
public void ConstructorSegmentSizeZeroThrowsArgumentException()
|
|
{
|
|
var ex = Assert.Throws<ArgumentException>(() => new SegmentedPool(segmentSize: 0));
|
|
Assert.Equal("Segment size must be greater than zero. (Parameter 'segmentSize')", ex.Message);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that an ArgumentException is raised if initialSegment is 0
|
|
/// </summary>
|
|
[Fact]
|
|
public void ConstructorInitialSegmentCountLessThanOneThrowsArgumentException()
|
|
{
|
|
var ex = Assert.Throws<ArgumentException>(() => new SegmentedPool(initialSegments: 0));
|
|
Assert.Equal("Initial segments count must be at least 1. (Parameter 'initialSegments')", ex.Message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that valid arguments create valid object
|
|
/// </summary>
|
|
[Fact]
|
|
public void ConstructorValidArgumentsIsValidObject()
|
|
{
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
|
|
try
|
|
{
|
|
Assert.False(pool.IsDisposed);
|
|
Assert.Equal(segmentSize, pool.CurrentSegmentSize);
|
|
Assert.Equal(initialSegments, (int)(pool.TotalAllocatedBytes / segmentSize));
|
|
Assert.Equal(1, pool.ActiveSegmentCount); // one is active
|
|
Assert.True(pool.TotalAllocatedBytes >= segmentSize * (nuint)initialSegments);
|
|
Assert.Equal(0u, pool.TotalUsedBytes);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that valid arguments but the allocation of the initial segments fails throws OutOfMemoryException
|
|
/// </summary>
|
|
[Fact]
|
|
public void ConstructorValidArgumentsButAllocationOfinitialSegmentsFailsThrowsOutOfMemoryException()
|
|
{
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
FailingAllocator failingAllocator = new FailingAllocator(failAfterNSegmentsAllocated: 1);
|
|
|
|
var ex = Assert.Throws<OutOfMemoryException>(() => new SegmentedPool(segmentSize, initialSegments, failingAllocator));
|
|
Assert.Equal("The allocator has failed!", ex.Message);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that SetSegmentSize with the new size set to Zero throws ArgumentOutOfRangeException
|
|
/// </summary>
|
|
[Fact]
|
|
public void SetSegmentSizeWithSizeOfZeroThrowsArgumentOutOfRangeException()
|
|
{
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => pool.SetSegmentSize(0));
|
|
Assert.Equal("Segment size must be greater than zero. (Parameter 'newSize')", ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that SetSegmentSize changes the allocated SegmentSize
|
|
/// </summary>
|
|
[Fact]
|
|
public void SetSegmentSizeChangesTheSegmentSize()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
nuint newSegmentSize = 4096;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
Assert.Equal(segmentSize, pool.CurrentSegmentSize);
|
|
pool.SetSegmentSize(newSegmentSize);
|
|
Assert.NotEqual(segmentSize, pool.CurrentSegmentSize);
|
|
Assert.Equal(newSegmentSize, pool.CurrentSegmentSize);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that ResetSegmentSize changes the allocated SegmentSize to the default 4 MiB
|
|
/// </summary>
|
|
[Fact]
|
|
public void ReetSegmentSizeChangesTheSegmentSizeToDefault()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
nuint defaultSize = 4194304; // 4 MiB
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
Assert.Equal(segmentSize, pool.CurrentSegmentSize);
|
|
pool.ResetSegmentSize();
|
|
Assert.NotEqual(segmentSize, pool.CurrentSegmentSize);
|
|
Assert.Equal(defaultSize, pool.CurrentSegmentSize);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that SetSegmentSize called with a valid argument but the SegmentedPool has already been disposed throws ObjectDisposedException
|
|
/// </summary>
|
|
[Fact]
|
|
public void SetSegmentSizeValidArgumentButAlreadyDisposedThrowsObjectDisposedException()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
var ex = Assert.Throws<ObjectDisposedException>(() => pool.SetSegmentSize(4096));
|
|
Assert.Equal("Cannot access a disposed object.\r\nObject name: 'UnmanagedMMU.SegmentedPool'.", ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that ResetSegmentSize called with a valid argument but the SegmentedPool has already been disposed throws ObjectDisposedException
|
|
/// </summary>
|
|
[Fact]
|
|
public void ResetSegmentSizeValidArgumentButAlreadyDisposedThrowsObjectDisposedException()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
var ex = Assert.Throws<ObjectDisposedException>(() => pool.ResetSegmentSize());
|
|
Assert.Equal("Cannot access a disposed object.\r\nObject name: 'UnmanagedMMU.SegmentedPool'.", ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Allocate a valid count and unamanged T is successful
|
|
/// </summary>
|
|
[Fact]
|
|
public void AllocateValidCountAndForGenericTSucceeds()
|
|
{
|
|
AllocateAndAssert<sbyte>();
|
|
AllocateAndAssert<byte>();
|
|
AllocateAndAssert<short>();
|
|
AllocateAndAssert<ushort>();
|
|
AllocateAndAssert<int>();
|
|
AllocateAndAssert<uint>();
|
|
AllocateAndAssert<long>();
|
|
AllocateAndAssert<ulong>();
|
|
AllocateAndAssert<nint>();
|
|
AllocateAndAssert<nuint>();
|
|
AllocateAndAssert<char>();
|
|
AllocateAndAssert<float>();
|
|
AllocateAndAssert<double>();
|
|
AllocateAndAssert<decimal>();
|
|
AllocateAndAssert<bool>();
|
|
}
|
|
|
|
private void AllocateAndAssert<T>() where T : unmanaged
|
|
{
|
|
SegmentedPool pool = new SegmentedPool();
|
|
|
|
try
|
|
{
|
|
Span<T> span = pool.Allocate<T>(100);
|
|
AssertSpanIsNotEmptyAndHasNElements(span, 100);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Allocate with an invalid count but valid unamanged T throws ArgumentOutOfRangeException
|
|
/// </summary>
|
|
[Fact]
|
|
public void AllocateInvalidCountThrowsArgumentOutOfRangeException()
|
|
{
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => pool.Allocate<int>(0));
|
|
Assert.Equal("Allocation count must be greater than zero. (Parameter 'count')", ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Allocate a valid count and unamanged T but the allocation is larger than the current segment is successful
|
|
/// </summary>
|
|
[Fact]
|
|
public void AllocateValidCountButAllocationIsLargerThanCurrentSegmentSucceeds()
|
|
{
|
|
// use a small segment on purpose
|
|
SegmentedPool pool = new SegmentedPool(segmentSize: 128);
|
|
|
|
try
|
|
{
|
|
Span<int> span = pool.Allocate<int>(100);
|
|
AssertSpanIsNotEmptyAndHasNElements(span, 100);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Allocate a valid count and unamanged T but there are no free segments
|
|
/// </summary>
|
|
[Fact]
|
|
public void AllocateValidCountButNoFreeSegmentsSucceeds()
|
|
{
|
|
// use a small segment on purpose
|
|
SegmentedPool pool = new SegmentedPool(segmentSize: 128, initialSegments: 1);
|
|
|
|
try
|
|
{
|
|
Span<byte> spanb = pool.Allocate<byte>(128);
|
|
AssertSpanIsNotEmptyAndHasNElements(spanb, 128);
|
|
Assert.Equal(0, pool.FreeSegmentCount);
|
|
|
|
Span<byte> spanb2 = pool.Allocate<byte>(128);
|
|
AssertSpanIsNotEmptyAndHasNElements(spanb2, 128);
|
|
Assert.Equal(2, pool.ActiveSegmentCount);
|
|
Assert.Equal(0, pool.FreeSegmentCount);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Allocate a valid count and unamanged T but the allocation size exceeds the segment size then the segment is switched Segment
|
|
/// </summary>
|
|
[Fact]
|
|
public void AllocateValidCountWhenAllocationExceedsSegmentSizeSucceedsSwitchesSegment()
|
|
{
|
|
nuint segmentSize = 1024;
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
int count = 300;
|
|
Assert.Equal(1, pool.FreeSegmentCount);
|
|
Span<int> span = pool.Allocate<int>(count);
|
|
AssertSpanIsNotEmptyAndHasNElements(span, count);
|
|
Assert.Equal(2, pool.ActiveSegmentCount);
|
|
Assert.Equal(1, pool.FreeSegmentCount);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Allocate a valid count and unamanged T and the allocaiton
|
|
/// </summary>
|
|
[Fact]
|
|
public void AllocateValidCountWhenFreeSegmentAvailableReusesSegment()
|
|
{
|
|
nuint segmentSize = 1024;
|
|
int initialSegments = 2; // one current + one free
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
|
|
try
|
|
{
|
|
// Fill _current segment almost completely
|
|
int sizeToFillCurrent = (int)(segmentSize / sizeof(int));
|
|
Assert.Equal(1, pool.ActiveSegmentCount);
|
|
Assert.Equal(1, pool.FreeSegmentCount);
|
|
Span<int> span1 = pool.Allocate<int>(sizeToFillCurrent - 1);
|
|
AssertSpanIsNotEmptyAndHasNElements(span1, sizeToFillCurrent - 1);
|
|
|
|
// triggers SwitchSegment
|
|
Span<int> span2 = pool.Allocate<int>(2);
|
|
|
|
AssertSpanIsNotEmptyAndHasNElements(span2, 2);
|
|
Assert.Equal(2, pool.ActiveSegmentCount);
|
|
Assert.Equal(0, pool.FreeSegmentCount);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Allocate called with a valid argument but the SegmentedPool has already been disposed throws ObjectDisposedException
|
|
/// </summary>
|
|
[Fact]
|
|
public void AllocateValidArgumentButAlreadyDisposedThrowsObjectDisposedException()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
var ex = Assert.Throws<ObjectDisposedException>(() => pool.Allocate<int>(123));
|
|
Assert.Equal("Cannot access a disposed object.\r\nObject name: 'UnmanagedMMU.SegmentedPool'.", ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Trim with the min Segment less than 0 throws ArgumentOutOfRangeException
|
|
/// </summary>
|
|
[Fact]
|
|
public void TrimInvalidArgumentThrowsArgumentOutOfRangeException()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => pool.Trim(-123));
|
|
Assert.Equal("minFreeSegments ('-123') must be a non-negative value. (Parameter 'minFreeSegments')\r\nActual value was -123.", ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Trim does not modify the total number of free segments if the minFreeSegment variable is greater than the number of free Segments
|
|
/// </summary>
|
|
[Fact]
|
|
public void TrimWhenFreeSegmentCountLessThanMinSegmentsDoesNothing()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 32;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
Assert.Equal(31, pool.FreeSegmentCount);
|
|
pool.Trim(128);
|
|
Assert.Equal(31, pool.FreeSegmentCount);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Trim doesmodify the total number of free segments if the minFreeSegment variable is less than the number of free Segments
|
|
/// </summary>
|
|
[Fact]
|
|
public void TrimWhenFreeSegmentGreaterThanMinSegmentsTrimsFreeSegmentsToNewSize()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 32;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
Assert.Equal(31, pool.FreeSegmentCount);
|
|
pool.Trim(16);
|
|
Assert.Equal(16, pool.FreeSegmentCount);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Trim called with a valid argument but the SegmentedPool has already been disposed throws ObjectDisposedException
|
|
/// </summary>
|
|
[Fact]
|
|
public void TrimValidArgumentButAlreadyDisposedThrowsObjectDisposedException()
|
|
{
|
|
|
|
nuint segmentSize = 1024; // 1 KiB for the test
|
|
int initialSegments = 2;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
var ex = Assert.Throws<ObjectDisposedException>(() => pool.Trim(16));
|
|
Assert.Equal("Cannot access a disposed object.\r\nObject name: 'UnmanagedMMU.SegmentedPool'.", ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Reset with trim false clears all active Segments and leaves the SegmentPool with a single active page
|
|
/// </summary>
|
|
[Fact]
|
|
public void ResetNoTrimClearsAllActivateSegments()
|
|
{
|
|
nuint segmentSize = 300; // 300 bytes for the test
|
|
int initialSegments = 8;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
Span<byte> testSpan1 = pool.Allocate<byte>(256);
|
|
Span<byte> testSpan2 = pool.Allocate<byte>(256);
|
|
Span<byte> testSpan3 = pool.Allocate<byte>(256);
|
|
Span<byte> testSpan4 = pool.Allocate<byte>(256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan1, 256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan2, 256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan3, 256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan4, 256);
|
|
|
|
Assert.Equal(4, pool.ActiveSegmentCount);
|
|
Assert.Equal(4, pool.FreeSegmentCount);
|
|
Assert.Equal(4 * 256, (int)pool.TotalUsedBytes);
|
|
Assert.Equal(300, (int)pool.CurrentSegmentSize);
|
|
Assert.Equal(8*300, (int)pool.TotalAllocatedBytes);
|
|
|
|
pool.Reset();
|
|
|
|
Assert.Equal(1, pool.ActiveSegmentCount);
|
|
Assert.Equal(7, pool.FreeSegmentCount);
|
|
Assert.Equal(0, (int)pool.TotalUsedBytes);
|
|
Assert.Equal(300, (int)pool.CurrentSegmentSize);
|
|
Assert.Equal(8 * 300, (int)pool.TotalAllocatedBytes);
|
|
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that Reset with trim true clears all active Segments and leaves the SegmentPool with a single active page and trims the free sements to 16
|
|
/// </summary>
|
|
[Fact]
|
|
public void ResetWithTrimClearsAllActivateSegments()
|
|
{
|
|
nuint segmentSize = 300; // 300 bytes for the test
|
|
int initialSegments = 64;
|
|
|
|
SegmentedPool pool = new SegmentedPool(segmentSize, initialSegments);
|
|
try
|
|
{
|
|
Span<byte> testSpan1 = pool.Allocate<byte>(256);
|
|
Span<byte> testSpan2 = pool.Allocate<byte>(256);
|
|
Span<byte> testSpan3 = pool.Allocate<byte>(256);
|
|
Span<byte> testSpan4 = pool.Allocate<byte>(256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan1, 256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan2, 256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan3, 256);
|
|
AssertSpanIsNotEmptyAndHasNElements(testSpan4, 256);
|
|
|
|
Assert.Equal(4, pool.ActiveSegmentCount);
|
|
Assert.Equal(60, pool.FreeSegmentCount);
|
|
Assert.Equal(4 * 256, (int)pool.TotalUsedBytes);
|
|
Assert.Equal(300, (int)pool.CurrentSegmentSize);
|
|
Assert.Equal(64 * 300, (int)pool.TotalAllocatedBytes);
|
|
|
|
pool.Reset(true);
|
|
|
|
Assert.Equal(1, pool.ActiveSegmentCount);
|
|
Assert.Equal(16, pool.FreeSegmentCount);
|
|
Assert.Equal(0, (int)pool.TotalUsedBytes);
|
|
Assert.Equal(300, (int)pool.CurrentSegmentSize);
|
|
Assert.Equal(17 * 300, (int)pool.TotalAllocatedBytes);
|
|
|
|
}
|
|
finally
|
|
{
|
|
pool.Dispose();
|
|
Assert.True(pool.IsDisposed);
|
|
}
|
|
}
|
|
}
|
|
}
|