public bool MoveNext() { if (_completed == _length) { _current = Memory<T>.Empty; return false; } if (_completed == 0) { var firstSegment = _offset >> SegmentedArrayHelper.GetSegmentShift<T>(); var offset = _offset & SegmentedArrayHelper.GetOffsetMask<T>(); var segment = _segments[firstSegment]; var remainingInSegment = segment.Length - offset; _current = segment.AsMemory().Slice(offset, Math.Min(remainingInSegment, _length)); _completed = _current.Length; return true; } else { var segment = _segments[(_completed + _offset) >> SegmentedArrayHelper.GetSegmentShift<T>()]; _current = segment.AsMemory().Slice(0, Math.Min(SegmentedArrayHelper.GetSegmentSize<T>(), _length - _completed)); _completed += _current.Length; return true; } }
public void CalculateOffsetMask(int segmentSize) { var expected = segmentSize switch { 1024 => 0x3FF, 2048 => 0x7FF, 4096 => 0xFFF, 8192 => 0x1FFF, 16384 => 0x3FFF, 32768 => 0x7FFF, 65536 => 0xFFFF, _ => throw ExceptionUtilities.Unreachable, }; Assert.Equal(expected, SegmentedArrayHelper.CalculateOffsetMask(segmentSize)); }
public void CalculateSegmentShift(int segmentSize) { var expected = segmentSize switch { 1024 => 10, 2048 => 11, 4096 => 12, 8192 => 13, 16384 => 14, 32768 => 15, 65536 => 16, _ => throw ExceptionUtilities.Unreachable, }; Assert.Equal(expected, SegmentedArrayHelper.CalculateSegmentShift(segmentSize)); }
public void CalculateSegmentSize(int elementSize) { var expected = elementSize switch { 1 => 65536, 2 => 32768, 3 => 16384, 4 => 16384, 5 => 16384, 6 => 8192, 7 => 8192, 8 => 8192, 9 => 8192, 10 => 8192, 16 => 4096, 32 => 2048, _ => throw ExceptionUtilities.Unreachable, }; Assert.Equal(expected, SegmentedArrayHelper.CalculateSegmentSize(elementSize)); }