From bcaaaa34a93f4a2b1da7529b7b3af47aa2a1b468 Mon Sep 17 00:00:00 2001 From: Wraith2 Date: Thu, 24 Oct 2019 22:30:00 +0100 Subject: [PATCH 1/2] add plp target buffer caching --- .../Data/SqlClient/TdsParserStateObject.cs | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index f46eee23a8..fec6a1dbfc 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -1910,7 +1910,7 @@ internal int ReadPlpBytesChunk(byte[] buff, int offset, int len) // Every time you call this method increment the offset and decrease len by the value of totalBytesRead internal bool TryReadPlpBytes(ref byte[] buff, int offset, int len, out int totalBytesRead) { - int bytesRead = 0; + int bytesRead; int bytesLeft; byte[] newbuf; ulong ignored; @@ -1928,16 +1928,27 @@ internal bool TryReadPlpBytes(ref byte[] buff, int offset, int len, out int tota return true; // No data } - Debug.Assert((_longlen != TdsEnums.SQL_PLP_NULL), - "Out of sync plp read request"); - + Debug.Assert(_longlen != TdsEnums.SQL_PLP_NULL, "Out of sync plp read request"); Debug.Assert((buff == null && offset == 0) || (buff.Length >= offset + len), "Invalid length sent to ReadPlpBytes()!"); + bytesLeft = len; // If total length is known up front, allocate the whole buffer in one shot instead of realloc'ing and copying over each time if (buff == null && _longlen != TdsEnums.SQL_PLP_UNKNOWNLEN) { - buff = new byte[(int)Math.Min((int)_longlen, len)]; + if (_snapshot != null) + { + // if there is a snapshot and it contains a stored plp buffer take it + // and try to use it if it is the right length + buff = _snapshot._plpBuffer; + _snapshot._plpBuffer = null; + } + + if ((ulong)(buff?.Length ?? 0) != _longlen) + { + // if the buffer is null or the wrong length create one to use + buff = new byte[(int)Math.Min((int)_longlen, len)]; + } } if (_longlenleft == 0) @@ -1982,13 +1993,26 @@ internal bool TryReadPlpBytes(ref byte[] buff, int offset, int len, out int tota _longlenleft -= (ulong)bytesRead; if (!result) { + if (_snapshot != null) + { + // a partial read has happened so store the target buffer in the snapshot + // so it can be re-used when another packet arrives and we read again + _snapshot._plpBuffer = buff; + } return false; } if (_longlenleft == 0) - { // Read the next chunk or cleanup state if hit the end + { + // Read the next chunk or cleanup state if hit the end if (!TryReadPlpLength(false, out ignored)) { + if (_snapshot != null) + { + // a partial read has happened so store the target buffer in the snapshot + // so it can be re-used when another packet arrives and we read again + _snapshot._plpBuffer = buff; + } return false; } } @@ -3941,8 +3965,10 @@ partial void SetStackInternal(string value) private NullBitmap _snapshotNullBitmapInfo; private _SqlMetaDataSet _snapshotCleanupMetaData; private _SqlMetaDataSetCollection _snapshotCleanupAltMetaDataSetArray; - private PLPData _plpData; - private TdsParserStateObject _stateObj; + + internal byte[] _plpBuffer; + + private readonly TdsParserStateObject _stateObj; private int _snapshotInBuffCount; private int _snapshotInBuffCurrent; From 33735e47f4fe329720cbcd4038987718568c8ee6 Mon Sep 17 00:00:00 2001 From: Wraith2 Date: Wed, 6 Nov 2019 23:40:00 +0000 Subject: [PATCH 2/2] resolve merge conflict --- .../src/Microsoft/Data/SqlClient/TdsParserStateObject.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs index fec6a1dbfc..931bb53f7e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs @@ -3967,8 +3967,8 @@ partial void SetStackInternal(string value) private _SqlMetaDataSetCollection _snapshotCleanupAltMetaDataSetArray; internal byte[] _plpBuffer; - - private readonly TdsParserStateObject _stateObj; + private PLPData _plpData; + private TdsParserStateObject _stateObj; private int _snapshotInBuffCount; private int _snapshotInBuffCurrent;