Add segmented buffering and sequence reads to ArrayPoolBufferWriter<T> - #1216
Open
paulomorgado wants to merge 1 commit into
Open
paulomorgado wants to merge 1 commit into
paulomorgado wants to merge 1 commit into
Conversation
Retain completed pooled arrays instead of copying data on every growth, and expose written data through GetReadOnlySequence(). Grow segments geometrically and consolidate only when a contiguous view is requested. Keep capacity and write counts within supported limits, avoid consolidation during char formatting and debugger inspection, and add tests for buffer ownership, failure recovery, and boundary conditions.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1214
Linked issue: Add segmented buffering and sequence reads to
ArrayPoolBufferWriter<T>ArrayPoolBufferWriter<T>now retains completed pooled arrays as segments rather than copying the entire written prefix each time it grows. The newGetReadOnlySequence()exposes written data without copying its contents, benefiting repeated writes when consumers can accept a sequence.Design choices: Buffers grow geometrically up to 1 MiB, while larger requested segments are rounded to a power of two. The writer rents the next buffer before changing ownership so a failed rent leaves existing data intact.
WrittenMemory,WrittenSpan,IMemoryOwner<T>.Memory, andDangerousGetArray()continue to provide a contiguous view by consolidating on demand.Clear()andDispose()return retained buffers to the pool; characterToString()and debugger inspection avoid incidental consolidation. Counts and writable views are limited toint.MaxValueelements.PR Checklist
Potential behavioral breaking change:
CapacityThere are no removed public APIs or changed signatures, but
Capacityno longer describes the length of one contiguous underlying array. After growth, it reports the completed written count plus the capacity of the active segment, capped atint.MaxValue; unwritten tails of completed segments are not counted.FreeCapacityis the writable portion of the active segment, soCapacity - WrittenCount == FreeCapacity. Callers that rely on specific capacity values or assumeCapacityguarantees one contiguous buffer may need to useGetSpan(sizeHint)for writes or a contiguous-view API for reads. Writes exceeding the supportedint.MaxValuetotal length are rejected.Other information
Like
WrittenSpanandWrittenMemory,GetReadOnlySequence()is a non-owning view into pooled buffers, not a persistent snapshot. The additional interaction to note is that merely requesting a contiguous view after a segmented sequence can consolidate the writer and return the arrays underlying that sequence to the pool, invalidating it without another write.Automatic compaction of completed buffers was considered, but merging them would copy already-written data even for callers that only consume
GetReadOnlySequence(). Keeping the segments intact avoids that unnecessary cost; data is copied only when a contiguous view is requested.