@@ -16,39 +16,17 @@ namespace SixLabors.ImageSharp.IO
1616 /// </summary>
1717 internal sealed class ChunkedMemoryStream : Stream
1818 {
19- /// <summary>
20- /// The default length in bytes of each buffer chunk when allocating large buffers.
21- /// </summary>
22- public const int DefaultLargeChunkSize = 1024 * 1024 * 4 ; // 4 Mb
23-
24- /// <summary>
25- /// The threshold at which to switch to using the large buffer.
26- /// </summary>
27- public const int DefaultLargeChunkThreshold = DefaultLargeChunkSize / 4 ; // 1 Mb
28-
29- /// <summary>
30- /// The default length in bytes of each buffer chunk when allocating small buffers.
31- /// </summary>
32- public const int DefaultSmallChunkSize = DefaultLargeChunkSize / 32 ; // 128 Kb
33-
3419 // The memory allocator.
3520 private readonly MemoryAllocator allocator ;
3621
3722 // Data
3823 private MemoryChunk memoryChunk ;
3924
40- // The length, in bytes, of each large buffer chunk
41- private readonly int largeChunkSize ;
42-
43- // The length, in bytes of the total allocation threshold that triggers switching from
44- // small to large buffer chunks.
45- private readonly int largeChunkThreshold ;
46-
47- // The current length, in bytes, of each buffer chunk
48- private int chunkSize ;
25+ // The total number of allocated chunks
26+ private int chunkCount ;
4927
50- // The total allocation length, in bytes
51- private int totalAllocation ;
28+ // The length of the largest contiguous buffer that can be handled by the allocator.
29+ private readonly int allocatorCapacity ;
5230
5331 // Has the stream been disposed.
5432 private bool isDisposed ;
@@ -72,12 +50,7 @@ public ChunkedMemoryStream(MemoryAllocator allocator)
7250 {
7351 Guard . NotNull ( allocator , nameof ( allocator ) ) ;
7452
75- // Tweak our buffer sizes to take the minimum of the provided buffer sizes
76- // or values scaled from the allocator buffer capacity which provides us with the largest
77- // available contiguous buffer size.
78- this . largeChunkSize = Math . Min ( DefaultLargeChunkSize , allocator . GetBufferCapacityInBytes ( ) ) ;
79- this . largeChunkThreshold = Math . Min ( DefaultLargeChunkThreshold , this . largeChunkSize / 4 ) ;
80- this . chunkSize = Math . Min ( DefaultSmallChunkSize , this . largeChunkSize / 32 ) ;
53+ this . allocatorCapacity = allocator . GetBufferCapacityInBytes ( ) ;
8154 this . allocator = allocator ;
8255 }
8356
@@ -236,7 +209,7 @@ protected override void Dispose(bool disposing)
236209 this . memoryChunk = null ;
237210 this . writeChunk = null ;
238211 this . readChunk = null ;
239- this . totalAllocation = 0 ;
212+ this . chunkCount = 0 ;
240213 }
241214 finally
242215 {
@@ -548,13 +521,10 @@ private void EnsureNotDisposed()
548521 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
549522 private MemoryChunk AllocateMemoryChunk ( )
550523 {
551- if ( this . totalAllocation >= this . largeChunkThreshold )
552- {
553- this . chunkSize = this . largeChunkSize ;
554- }
555-
556- IMemoryOwner < byte > buffer = this . allocator . Allocate < byte > ( this . chunkSize ) ;
557- this . totalAllocation += this . chunkSize ;
524+ // Tweak our buffer sizes to take the minimum of the provided buffer sizes
525+ // or the allocator buffer capacity which provides us with the largest
526+ // available contiguous buffer size.
527+ IMemoryOwner < byte > buffer = this . allocator . Allocate < byte > ( Math . Min ( this . allocatorCapacity , GetChunkSize ( this . chunkCount ++ ) ) ) ;
558528
559529 return new MemoryChunk
560530 {
@@ -573,6 +543,16 @@ private void ReleaseMemoryChunks(MemoryChunk chunk)
573543 }
574544 }
575545
546+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
547+ private static int GetChunkSize ( int i )
548+ {
549+ #pragma warning disable IDE1006 // Naming Styles
550+ const int _128K = 1 << 17 ;
551+ const int _4M = 1 << 22 ;
552+ return i < 16 ? _128K * ( 1 << ( i / 4 ) ) : _4M ;
553+ #pragma warning restore IDE1006 // Naming Styles
554+ }
555+
576556 private sealed class MemoryChunk : IDisposable
577557 {
578558 private bool isDisposed ;
0 commit comments