Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Commit

Permalink
Removed operator+ from Position (#2041)
Browse files Browse the repository at this point in the history
* Added ISequence.Seek

* Remove Position.GetItem and Position_op+
  • Loading branch information
KrzysztofCwalina authored Jan 9, 2018
1 parent c1286b4 commit 724b3ce
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,46 @@ public bool TryGet(ref Position position, out ReadOnlyMemory<byte> item, bool ad
throw new NotImplementedException();
}

public Position Seek(Position origin, long offset)
{
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));

switch (Kind)
{
case Type.Array:
{
var (array, index) = origin.Get<byte[]>();
if (index + offset > array.Length) throw new ArgumentOutOfRangeException(nameof(offset));
return new Position(array, (int)(index + offset));
}
case Type.OwnedMemory:
{
var (om, index) = origin.Get<OwnedMemory<byte>>();
if (index + offset > om.Length) throw new ArgumentOutOfRangeException(nameof(offset));
return new Position(om, (int)(index + offset));
}
case Type.MemoryList:
var previous = origin;
while (TryGet(ref origin, out var memory))
{
var length = memory.Length;
if (length < offset)
{
offset -= length;
previous = origin;
}
else
{
var (segment, index) = previous.Get<IBufferList>();
return new Position(segment, (int)(index + offset));
}
}
throw new ArgumentOutOfRangeException(nameof(offset));
default:
throw new NotSupportedException();
}
}

enum Type : byte
{
Array,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,28 @@ public bool TryGet(ref Position position, out Memory<byte> item, bool advance =
throw new NotImplementedException();
}

public Position Seek(Position origin, long offset)
{
if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset));

var previous = origin;
while(TryGet(ref origin, out var memory))
{
var length = memory.Length;
if(length < offset)
{
offset -= length;
previous = origin;
}
else
{
var (segment, index) = origin.Get<IBufferList>();
return new Position(segment, (int)(index + offset));
}
}
throw new ArgumentOutOfRangeException(nameof(offset));
}

enum Type : byte
{
Array,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static long IndexOf<TSequence>(TSequence sequence, byte v1, byte v2) wher
var index = MemoryExtensions.IndexOf(memory.Span, value);
if (index != -1)
{
result += index;
result = sequence.Seek(result, index);
return result;
}
result = position;
Expand All @@ -98,7 +98,7 @@ public static long IndexOf<TSequence>(TSequence sequence, byte v1, byte v2) wher
var span = memory.Span;
if(span.Length > index)
{
result += (int)index;
result = sequence.Seek(result, index);
return result;
}
index -= span.Length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,13 @@ public Enumerator GetEnumerator()
return new Enumerator(this);
}

public Position Seek(Position position, long count)
public Position Seek(Position origin, long offset)
{
if (count < 0)
if (offset < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
throw new ArgumentOutOfRangeException(nameof(offset));
}
return Seek(position, BufferEnd, count, false);
return Seek(origin, BufferEnd, offset, false);
}

public bool TryGet(ref Position cursor, out ReadOnlyMemory<byte> data, bool advance = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public BufferReader(TSequence buffer)

public int Index => _index;

public Position Position => _currentPosition + _index;
public Position Position => _sequence.Seek(_currentPosition, _index);

public ReadOnlySpan<byte> CurrentSegment => _currentSpan;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ private static long GetLength(Position begin, Position end)
switch (segment)
{
case IBufferList bufferSegment:
return GetLength(bufferSegment, begin.Index, end.GetSegment<IBufferList>(), end.Index);
return GetLength(bufferSegment, begin.Index, (IBufferList)end.Segment, end.Index);
case byte[] _:
case OwnedMemory<byte> _:
return end.Index - begin.Index;
Expand Down Expand Up @@ -189,7 +189,8 @@ private static void BoundsCheck(Position end, Position newCursor)
}
return;
case IBufferList memoryList:
if(newCursor.GetSegment<IBufferList>().VirtualIndex - end.Index > memoryList.VirtualIndex - newCursor.Index)
var segment = (IBufferList)newCursor.Segment;
if(segment.VirtualIndex - end.Index > memoryList.VirtualIndex - newCursor.Index)
{
ThrowHelper.ThrowCursorOutOfBoundsException();
}
Expand Down
2 changes: 2 additions & 0 deletions src/System.Buffers.Primitives/System/Collections/ISequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public interface ISequence<T>
/// <remarks></remarks>
bool TryGet(ref Position position, out T item, bool advance = true);

Position Seek(Position origin, long offset);

Position Start { get; }
}
}
18 changes: 0 additions & 18 deletions src/System.Buffers.Primitives/System/Collections/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,9 @@ public Position(object segment)
return (segment, _index);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T GetSegment<T>()
{
switch (Segment)
{
case null:
return default;
case T segment:
return segment;
}

ThrowHelper.ThrowInvalidOperationException(ExceptionResource.UnexpectedSegmentType);
return default;
}

public static bool operator ==(Position left, Position right) => left._index == right._index && left._segment == right._segment;
public static bool operator !=(Position left, Position right) => left._index != right._index || left._segment != right._segment;

public static Position operator +(Position value, int index)
=> new Position(value._segment, value._index + index);

[EditorBrowsable(EditorBrowsableState.Never)]
public bool Equals(Position position) => this == position;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,12 @@ public sealed class ArrayList<T> : ISequence<T>

public bool TryGet(ref Position position, out T item, bool advance = true) =>
_items.TryGet(ref position, out item, advance);

public Position Seek(Position origin, long offset)
{
long index = (int)origin + offset;
if (index < 0 || index >= Length) throw new ArgumentOutOfRangeException(nameof(offset));
return new Position(null, (int)index);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public bool TryGet(ref Position position, out T item, bool advance = true)
int index = (int)position;
if (index < _count) {
item = _array[index];
if (advance) { position +=1; }
if (advance) { position = new Position(null, index+1); }
return true;
}

Expand Down
17 changes: 5 additions & 12 deletions src/System.IO.Pipelines.Extensions/ReadableBufferSequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,12 @@ public ReadableBufferSequence(ReadOnlyBuffer buffer) : this()
_buffer = buffer;
}

public Position Start => new Position(_buffer.Start.Segment, _buffer.Start.Index);
public Position Start => _buffer.Start;

public bool TryGet(ref Position position, out ReadOnlyMemory<byte> item, bool advance = true)
{
var (data, index) = position.Get<object>();
var p = new Position(data, index);
var result = _buffer.TryGet(ref p, out item);
if (advance)
{
position = new Position(p.Segment, p.Index);
}
public Position Seek(Position origin, long offset)
=> _buffer.Seek(origin, offset);

return result;
}
public bool TryGet(ref Position position, out ReadOnlyMemory<byte> item, bool advance = true)
=> _buffer.TryGet(ref position, out item, advance);
}
}
2 changes: 1 addition & 1 deletion src/System.IO.Pipelines/System/IO/Pipelines/Pipe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ void IPipeReader.Advance(Position consumed, Position examined)
return;
}

var consumedSegment = consumed.GetSegment<BufferSegment>();
var consumedSegment = (BufferSegment)consumed.Segment;

returnStart = _readHead;
returnEnd = consumedSegment;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,13 @@ public SequenceEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
return new SequenceEnumerator<KeyValuePair<K, V>>(this);
}

public Position Seek(Position origin, long offset)
{
if (offset<0) throw new ArgumentOutOfRangeException(nameof(offset));
while (offset-- > 0 && TryGet(ref origin, out _));
if (offset == 0) return origin;
throw new ArgumentOutOfRangeException(nameof(offset));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,23 @@ public SequenceEnumerator<T> GetEnumerator()
{
return new SequenceEnumerator<T>(this);
}

public Position Seek(Position origin, long offset)
{
if (offset < 0) throw new InvalidOperationException("cannot seek backwards");
var (node, index) = origin.Get<Node>();
while(offset-- > 0)
{
if (node != null)
{
node = node._next;
}
else
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
}
return new Position(node, 0);
}
}
}

0 comments on commit 724b3ce

Please sign in to comment.