-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Open
Labels
area-System.Memorybughelp wanted[up-for-grabs] Good issue for external contributors[up-for-grabs] Good issue for external contributorsin-prThere is an active PR which will close this issue when it is mergedThere is an active PR which will close this issue when it is merged
Milestone
Description
The behavior of Slice(offset, SequencePosition) should match GetPosition(offset) and Slice(offset).
I should be able to slice a ReadOnlySequence past the current sequence if the next one is empty (for example: [97] -> []).
[Fact]
public static void ReadOnlySequenceTest()
{
string jsonString = "a";
ReadOnlyMemory<byte> dataMemory = Encoding.UTF8.GetBytes(jsonString);
var firstSegment = new BufferSegment<byte>(dataMemory.Slice(0, 1));
ReadOnlyMemory<byte> secondMem = dataMemory.Slice(0, 0);
BufferSegment<byte> secondSegment = firstSegment.Append(secondMem);
// A two segment sequence where the second one is empty: [a]-> []
var sequence = new ReadOnlySequence<byte>(firstSegment, 0, secondSegment, secondMem.Length);
SequencePosition expectedPosition = sequence.GetPosition(1);
Console.WriteLine(expectedPosition.GetInteger()); // 0
Console.WriteLine(expectedPosition.GetObject()); // System.Text.Json.Tests.BufferSegment`1[System.Byte]
Assert.True(((ReadOnlySequenceSegment<byte>)expectedPosition.GetObject()).Memory.IsEmpty);
SequencePosition actualPosition = sequence.Slice(1).Start;
Console.WriteLine(actualPosition.GetInteger()); // 0
Console.WriteLine(actualPosition.GetObject()); // System.Text.Json.Tests.BufferSegment`1[System.Byte]
Assert.True(((ReadOnlySequenceSegment<byte>)actualPosition.GetObject()).Memory.IsEmpty);
Assert.Equal(expectedPosition, actualPosition); // True
SequencePosition actualPosition2 = sequence.GetPosition(1, sequence.Start);
Console.WriteLine(actualPosition2.GetInteger()); // 0
Console.WriteLine(actualPosition2.GetObject()); // System.Text.Json.Tests.BufferSegment`1[System.Byte]
Assert.True(((ReadOnlySequenceSegment<byte>)actualPosition2.GetObject()).Memory.IsEmpty);
// System.ArgumentOutOfRangeException : Specified argument was out of the range of valid values.
/*
System.ArgumentOutOfRangeException : Specified argument was out of the range of valid values.
Parameter name: start
Stack Trace:
E:\GitHub\Fork\corefx\src\System.Memory\src\System\ThrowHelper.cs(31,0): at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument)
E:\GitHub\Fork\corefx\src\System.Memory\src\System\Buffers\ReadOnlySequence.cs(281,0): at System.Buffers.ReadOnlySequence`1.Slice(Int64 start, SequencePosition end)
E:\GitHub\Fork\corefx\src\System.Memory\src\System\Buffers\ReadOnlySequence.cs(388,0): at System.Buffers.ReadOnlySequence`1.Slice(Int32 start, SequencePosition end)
E:\GitHub\Fork\corefx\src\System.Text.Json\tests\Utf8JsonReaderTests.TryGet.cs(357,0): at System.Text.Json.Tests.Utf8JsonReaderTests.ReadOnlySequenceTest()
*/
sequence = sequence.Slice(1, sequence.Start);
}We need to use the Slice overload that takes a SequencePosition for performance to avoid having to scan the segments from the beginning every time. Using GetPosition with long is too slow:
https://github.com/dotnet/corefxlab/blob/63ef1a5db4fdbfcf9822b8cd2cbc3921b3d3cb9e/src/System.Text.JsonLab/System/Text/Json/JsonUtf8Reader.cs#L112
cc @pakrym, @davidfowl
Copilot
Metadata
Metadata
Assignees
Labels
area-System.Memorybughelp wanted[up-for-grabs] Good issue for external contributors[up-for-grabs] Good issue for external contributorsin-prThere is an active PR which will close this issue when it is mergedThere is an active PR which will close this issue when it is merged