/// <inheritdoc /> internal override MemoryGroup <T> AllocateGroup <T>( long totalLength, int bufferAlignment, AllocationOptions options = AllocationOptions.None) { long totalLengthInBytes = totalLength * Unsafe.SizeOf <T>(); if (totalLengthInBytes <= this.sharedArrayPoolThresholdInBytes) { var buffer = new SharedArrayPoolBuffer <T>((int)totalLength); return(MemoryGroup <T> .CreateContiguous(buffer, options.Has(AllocationOptions.Clean))); } if (totalLengthInBytes <= this.poolBufferSizeInBytes) { // Optimized path renting single array from the pool UnmanagedMemoryHandle mem = this.pool.Rent(); if (mem.IsValid) { UnmanagedBuffer <T> buffer = this.pool.CreateGuardedBuffer <T>(mem, (int)totalLength, options.Has(AllocationOptions.Clean)); return(MemoryGroup <T> .CreateContiguous(buffer, options.Has(AllocationOptions.Clean))); } } // Attempt to rent the whole group from the pool, allocate a group of unmanaged buffers if the attempt fails: if (MemoryGroup <T> .TryAllocate(this.pool, totalLength, bufferAlignment, options, out MemoryGroup <T> poolGroup)) { return(poolGroup); } return(MemoryGroup <T> .Allocate(this.nonPoolAllocator, totalLength, bufferAlignment, options)); }
/// <inheritdoc /> public override IMemoryOwner <T> Allocate <T>( int length, AllocationOptions options = AllocationOptions.None) { Guard.MustBeGreaterThanOrEqualTo(length, 0, nameof(length)); int lengthInBytes = length * Unsafe.SizeOf <T>(); if (lengthInBytes <= this.sharedArrayPoolThresholdInBytes) { var buffer = new SharedArrayPoolBuffer <T>(length); if (options.Has(AllocationOptions.Clean)) { buffer.GetSpan().Clear(); } return(buffer); } if (lengthInBytes <= this.poolBufferSizeInBytes) { UnmanagedMemoryHandle mem = this.pool.Rent(); if (mem.IsValid) { UnmanagedBuffer <T> buffer = this.pool.CreateGuardedBuffer <T>(mem, length, options.Has(AllocationOptions.Clean)); return(buffer); } } return(this.nonPoolAllocator.Allocate <T>(length, options)); }
static void RunTest() { using (var buffer = new SharedArrayPoolBuffer <byte>(900)) { Assert.Equal(900, buffer.GetSpan().Length); buffer.GetSpan().Fill(42); } byte[] array = ArrayPool <byte> .Shared.Rent(900); byte[] expected = Enumerable.Repeat((byte)42, 900).ToArray(); Assert.True(expected.AsSpan().SequenceEqual(array.AsSpan(0, 900))); }