Permalink
Browse files

Use local functions.

Note that we avoid capturing local variables, because this causes the compiler-generated code to allocate a new class to store them. By passing the parameters (and aliasing them with a different parameter name in the local function), we get zero extra allocations.
  • Loading branch information...
bgrainger committed Apr 1, 2017
1 parent 5516807 commit 27809b8613eab6d098161029733170aed8801876
@@ -162,42 +162,38 @@ private ValueTask<Row> ScanRowAsync(IOBehavior ioBehavior, Row row, Cancellation
if (BufferState == ResultSetState.HasMoreData || BufferState == ResultSetState.NoMoreData || BufferState == ResultSetState.None)
return new ValueTask<Row>((Row)null);
var payloadTask = Session.ReceiveReplyAsync(ioBehavior, cancellationToken);
return payloadTask.IsCompletedSuccessfully
? new ValueTask<Row>(ScanRowAsyncRemainder(row, payloadTask.Result))
: new ValueTask<Row>(ScanRowAsyncAwaited(row, payloadTask.AsTask()));
}
var payloadValueTask = Session.ReceiveReplyAsync(ioBehavior, cancellationToken);
return payloadValueTask.IsCompletedSuccessfully
? new ValueTask<Row>(ScanRowAsyncRemainder(payloadValueTask.Result))
: new ValueTask<Row>(ScanRowAsyncAwaited(payloadValueTask.AsTask()));
private async Task<Row> ScanRowAsyncAwaited(Row row, Task<PayloadData> payloadTask)
{
var payload = await payloadTask.ConfigureAwait(false);
return ScanRowAsyncRemainder(row, payload);
}
async Task<Row> ScanRowAsyncAwaited(Task<PayloadData> payloadTask) => ScanRowAsyncRemainder(await payloadTask.ConfigureAwait(false));
private Row ScanRowAsyncRemainder(Row row, PayloadData payload)
{
if (EofPayload.IsEof(payload))
Row ScanRowAsyncRemainder(PayloadData payload)
{
var eof = EofPayload.Create(payload);
BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData;
m_rowBuffered = null;
return null;
}
if (EofPayload.IsEof(payload))
{
var eof = EofPayload.Create(payload);
BufferState = (eof.ServerStatus & ServerStatus.MoreResultsExist) == 0 ? ResultSetState.NoMoreData : ResultSetState.HasMoreData;
m_rowBuffered = null;
return null;
}
var reader = new ByteArrayReader(payload.ArraySegment);
for (var column = 0; column < m_dataOffsets.Length; column++)
{
var length = checked((int) ReadFieldLength(reader));
m_dataLengths[column] = length == -1 ? 0 : length;
m_dataOffsets[column] = length == -1 ? -1 : reader.Offset;
reader.Offset += m_dataLengths[column];
}
var reader = new ByteArrayReader(payload.ArraySegment);
for (var column = 0; column < m_dataOffsets.Length; column++)
{
var length = checked((int) ReadFieldLength(reader));
m_dataLengths[column] = length == -1 ? 0 : length;
m_dataOffsets[column] = length == -1 ? -1 : reader.Offset;
reader.Offset += m_dataLengths[column];
}
if (row == null)
row = new Row(this);
row.SetData(m_dataLengths, m_dataOffsets, payload.ArraySegment.Array);
m_rowBuffered = row;
return row;
if (row == null)
row = new Row(this);
row.SetData(m_dataLengths, m_dataOffsets, payload.ArraySegment.Array);
m_rowBuffered = row;
return row;
}
}
private static long ReadFieldLength(ByteArrayReader reader)
@@ -15,14 +15,15 @@ public SocketByteHandler(Socket socket)
public ValueTask<int> ReadBytesAsync(ArraySegment<byte> buffer, IOBehavior ioBehavior)
{
if (ioBehavior == IOBehavior.Asynchronous)
{
return new ValueTask<int>(DoReadBytesAsync(buffer));
}
else
return (ioBehavior == IOBehavior.Asynchronous) ?
new ValueTask<int>(DoReadBytesAsync(buffer)) :
new ValueTask<int>(m_socket.Receive(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None));
async Task<int> DoReadBytesAsync(ArraySegment<byte> buffer_)
{
var bytesRead = m_socket.Receive(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None);
return new ValueTask<int>(bytesRead);
m_socketAwaitable.EventArgs.SetBuffer(buffer_.Array, buffer_.Offset, buffer_.Count);
await m_socket.ReceiveAsync(m_socketAwaitable);
return m_socketAwaitable.EventArgs.BytesTransferred;
}
}
@@ -37,20 +38,13 @@ public ValueTask<int> WriteBytesAsync(ArraySegment<byte> data, IOBehavior ioBeha
m_socket.Send(data.Array, data.Offset, data.Count, SocketFlags.None);
return default(ValueTask<int>);
}
}
private async Task<int> DoReadBytesAsync(ArraySegment<byte> buffer)
{
m_socketAwaitable.EventArgs.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
await m_socket.ReceiveAsync(m_socketAwaitable);
return m_socketAwaitable.EventArgs.BytesTransferred;
}
private async Task<int> DoWriteBytesAsync(ArraySegment<byte> payload)
{
m_socketAwaitable.EventArgs.SetBuffer(payload.Array, payload.Offset, payload.Count);
await m_socket.SendAsync(m_socketAwaitable);
return 0;
async Task<int> DoWriteBytesAsync(ArraySegment<byte> data_)
{
m_socketAwaitable.EventArgs.SetBuffer(data_.Array, data_.Offset, data_.Count);
await m_socket.SendAsync(m_socketAwaitable);
return 0;
}
}
readonly Socket m_socket;
@@ -13,15 +13,12 @@ public StreamByteHandler(Stream stream)
public ValueTask<int> ReadBytesAsync(ArraySegment<byte> buffer, IOBehavior ioBehavior)
{
if (ioBehavior == IOBehavior.Asynchronous)
{
return new ValueTask<int>(DoReadBytesAsync(buffer));
}
else
{
var bytesRead = m_stream.Read(buffer.Array, buffer.Offset, buffer.Count);
return new ValueTask<int>(bytesRead);
}
return (ioBehavior == IOBehavior.Asynchronous) ?
new ValueTask<int>(DoReadBytesAsync(buffer)) :
new ValueTask<int>(m_stream.Read(buffer.Array, buffer.Offset, buffer.Count));
async Task<int> DoReadBytesAsync(ArraySegment<byte> buffer_) =>
await m_stream.ReadAsync(buffer_.Array, buffer_.Offset, buffer_.Count).ConfigureAwait(false);
}
public ValueTask<int> WriteBytesAsync(ArraySegment<byte> data, IOBehavior ioBehavior)
@@ -35,18 +32,12 @@ public ValueTask<int> WriteBytesAsync(ArraySegment<byte> data, IOBehavior ioBeha
m_stream.Write(data.Array, data.Offset, data.Count);
return default(ValueTask<int>);
}
}
private async Task<int> DoReadBytesAsync(ArraySegment<byte> buffer)
{
var bytesRead = await m_stream.ReadAsync(buffer.Array, buffer.Offset, buffer.Count).ConfigureAwait(false);
return bytesRead;
}
private async Task<int> DoWriteBytesAsync(ArraySegment<byte> payload)
{
await m_stream.WriteAsync(payload.Array, payload.Offset, payload.Count).ConfigureAwait(false);
return 0;
async Task<int> DoWriteBytesAsync(ArraySegment<byte> data_)
{
await m_stream.WriteAsync(data_.Array, data_.Offset, data_.Count).ConfigureAwait(false);
return 0;
}
}
readonly Stream m_stream;

0 comments on commit 27809b8

Please sign in to comment.