Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update external files and remove unused #93

Merged
merged 1 commit into from May 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
178 changes: 0 additions & 178 deletions src/Common/JsonUtils.cs

This file was deleted.

102 changes: 66 additions & 36 deletions src/Common/MemoryBufferWriter.cs
Expand Up @@ -6,7 +6,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -24,7 +23,7 @@ internal sealed class MemoryBufferWriter : Stream, IBufferWriter<byte>
private readonly int _minimumSegmentSize;
private int _bytesWritten;

private List<byte[]> _fullSegments;
private List<CompletedBuffer> _completedSegments;
private byte[] _currentSegment;
private int _position;

Expand Down Expand Up @@ -78,14 +77,14 @@ public static void Return(MemoryBufferWriter writer)

public void Reset()
{
if (_fullSegments != null)
if (_completedSegments != null)
{
for (var i = 0; i < _fullSegments.Count; i++)
for (var i = 0; i < _completedSegments.Count; i++)
{
ArrayPool<byte>.Shared.Return(_fullSegments[i]);
_completedSegments[i].Return();
}

_fullSegments.Clear();
_completedSegments.Clear();
}

if (_currentSegment != null)
Expand Down Expand Up @@ -120,13 +119,13 @@ public Span<byte> GetSpan(int sizeHint = 0)

public void CopyTo(IBufferWriter<byte> destination)
{
if (_fullSegments != null)
if (_completedSegments != null)
{
// Copy full segments
var count = _fullSegments.Count;
// Copy completed segments
var count = _completedSegments.Count;
for (var i = 0; i < count; i++)
{
destination.Write(_fullSegments[i]);
destination.Write(_completedSegments[i].Span);
}
}

Expand All @@ -135,9 +134,9 @@ public void CopyTo(IBufferWriter<byte> destination)

public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
{
if (_fullSegments == null)
if (_completedSegments == null)
{
// There is only one segment so write without async
// There is only one segment so write without awaiting.
return destination.WriteAsync(_currentSegment, 0, _position);
}

Expand All @@ -146,43 +145,52 @@ public override Task CopyToAsync(Stream destination, int bufferSize, Cancellatio

private void EnsureCapacity(int sizeHint)
{
// TODO: Use sizeHint
if (_currentSegment != null && _position < _currentSegment.Length)
// This does the Right Thing. It only subtracts _position from the current segment length if it's non-null.
// If _currentSegment is null, it returns 0.
var remainingSize = _currentSegment?.Length - _position ?? 0;

// If the sizeHint is 0, any capacity will do
// Otherwise, the buffer must have enough space for the entire size hint, or we need to add a segment.
if ((sizeHint == 0 && remainingSize > 0) || (sizeHint > 0 && remainingSize >= sizeHint))
{
// We have capacity in the current segment
return;
}

AddSegment();
AddSegment(sizeHint);
}

private void AddSegment()
private void AddSegment(int sizeHint = 0)
{
if (_currentSegment != null)
{
// We're adding a segment to the list
if (_fullSegments == null)
if (_completedSegments == null)
{
_fullSegments = new List<byte[]>();
_completedSegments = new List<CompletedBuffer>();
}

_fullSegments.Add(_currentSegment);
// Position might be less than the segment length if there wasn't enough space to satisfy the sizeHint when
// GetMemory was called. In that case we'll take the current segment and call it "completed", but need to
// ignore any empty space in it.
_completedSegments.Add(new CompletedBuffer(_currentSegment, _position));
}

_currentSegment = ArrayPool<byte>.Shared.Rent(_minimumSegmentSize);
// Get a new buffer using the minimum segment size, unless the size hint is larger than a single segment.
_currentSegment = ArrayPool<byte>.Shared.Rent(Math.Max(_minimumSegmentSize, sizeHint));
_position = 0;
}

private async Task CopyToSlowAsync(Stream destination)
{
if (_fullSegments != null)
if (_completedSegments != null)
{
// Copy full segments
var count = _fullSegments.Count;
var count = _completedSegments.Count;
for (var i = 0; i < count; i++)
{
var segment = _fullSegments[i];
await destination.WriteAsync(segment, 0, segment.Length);
var segment = _completedSegments[i];
await destination.WriteAsync(segment.Buffer, 0, segment.Length);
}
}

Expand All @@ -200,15 +208,15 @@ public byte[] ToArray()

var totalWritten = 0;

if (_fullSegments != null)
if (_completedSegments != null)
{
// Copy full segments
var count = _fullSegments.Count;
var count = _completedSegments.Count;
for (var i = 0; i < count; i++)
{
var segment = _fullSegments[i];
segment.CopyTo(result, totalWritten);
totalWritten += segment.Length;
var segment = _completedSegments[i];
segment.Span.CopyTo(result.AsSpan(totalWritten));
totalWritten += segment.Span.Length;
}
}

Expand All @@ -229,15 +237,15 @@ public void CopyTo(Span<byte> span)

var totalWritten = 0;

if (_fullSegments != null)
if (_completedSegments != null)
{
// Copy full segments
var count = _fullSegments.Count;
var count = _completedSegments.Count;
for (var i = 0; i < count; i++)
{
var segment = _fullSegments[i];
segment.AsSpan().CopyTo(span.Slice(totalWritten));
totalWritten += segment.Length;
var segment = _completedSegments[i];
segment.Span.CopyTo(span.Slice(totalWritten));
totalWritten += segment.Span.Length;
}
}

Expand Down Expand Up @@ -285,7 +293,7 @@ public override void Write(byte[] buffer, int offset, int count)
}
}

#if NETCOREAPP2_1
#if NETCOREAPP2_2
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Azure SignalR SDK is netstandard2.0 only so this changing doesn't effect you.

public override void Write(ReadOnlySpan<byte> span)
{
if (_currentSegment != null && span.TryCopyTo(_currentSegment.AsSpan(_position)))
Expand All @@ -307,5 +315,27 @@ protected override void Dispose(bool disposing)
Reset();
}
}

/// <summary>
/// Holds a byte[] from the pool and a size value. Basically a Memory but guaranteed to be backed by an ArrayPool byte[], so that we know we can return it.
/// </summary>
private readonly struct CompletedBuffer
{
public byte[] Buffer { get; }
public int Length { get; }

public ReadOnlySpan<byte> Span => Buffer.AsSpan(0, Length);

public CompletedBuffer(byte[] buffer, int length)
{
Buffer = buffer;
Length = length;
}

public void Return()
{
ArrayPool<byte>.Shared.Return(Buffer);
}
}
}
}
}