-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Open
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-System.Buffers
Milestone
Description
Background and motivation
This is tangentially related to #100290 and the .NET 9 distributed caching epic; the proposed hybid-cache API will use ReadOnlySequence<byte> and IBufferWriter<byte> as the primary serializer APIs, but: not all serializers support these APIs (many do, note) - with Stream being the most common fallback.
API Proposal
// assembly: System.Memory
namespace System.Buffers;
public static class BuffersExtensions // pre-existing
{
+ public static Stream AsStream(this ReadOnlySequence<byte> value) => new ReadOnlySequenceStream(value);
+ public static Stream AsStream(this IBufferWriter<byte> value) => new BufferWriterStream(value);
}
+ internal sealed class ReadOnlySequenceStream : Stream {...}
+ internal sealed class BufferWriterStream : Stream {...}API Usage
ReadOnlySequence<byte> payload = ...
Customer obj = SomeRandomSerializer.Deserialize<Customer>(payload.AsStream());and
Customer obj = ...
IBufferWriter<byte> target = ...
SomeRandomSerializer.Serialize<Customer>(target.AsStream(), obj);The implementations would be internal, but:
ReadOnlySequenceStreamhas aCanRead: true,CanWrite: falseimplementation that supports seek etc; no additional buffer copies, just a few "where are we" counters, usingSequencePositioniteration and aReadOnlyMemory<byte>snapshot of the current segmentBufferWriterStreamhas aCanRead: false,CanWrite: trueimplementation that does not support seek; position and length are read-only and report the bytes written so far; no double-buffering - it is assumed (as a fundamental part ofIBufferWriter<byte>) that the underlyingIBufferWriter<byte>already does some internal work there when responding toGetSpan/GetMemory(such that they are affordable), so this would be duplicated effort and an additional mem-copy- in both cases, all APIs are synchronous, with the async APIs implemented as async-over-sync as efficiently as possible
- no need for fancy recycling, since we don't have any local buffers etc
Alternative Designs
The alternative is to use MemoryStream, which involves multiple additional copy operations and additional byte[] buffers.
Risks
None seen
Additional
I am happy to contribute the implementation effort.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-System.Buffers