Skip to content

Commit 3c6a66f

Browse files
committed
minor fixes and performance tuning
1 parent 8072f28 commit 3c6a66f

File tree

1 file changed

+93
-28
lines changed

1 file changed

+93
-28
lines changed

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 93 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,11 +1201,72 @@ public TdsOperationStatus TryReadByteArray(Span<byte> buff, int len)
12011201
{
12021202
return TryReadByteArray(buff, len, out _);
12031203
}
1204-
12051204
// NOTE: This method must be retriable WITHOUT replaying a snapshot
12061205
// Every time you call this method increment the offset and decrease len by the value of totalRead
12071206
public TdsOperationStatus TryReadByteArray(Span<byte> buff, int len, out int totalRead)
12081207
{
1208+
1209+
TdsParser.ReliabilitySection.Assert("unreliable call to ReadByteArray"); // you need to setup for a thread abort somewhere before you call this method
1210+
totalRead = 0;
1211+
1212+
#if DEBUG
1213+
if (_snapshot != null && _snapshot.DoPend())
1214+
{
1215+
_networkPacketTaskSource = new TaskCompletionSource<object>();
1216+
Interlocked.MemoryBarrier();
1217+
1218+
if (s_forcePendingReadsToWaitForUser)
1219+
{
1220+
_realNetworkPacketTaskSource = new TaskCompletionSource<object>();
1221+
_realNetworkPacketTaskSource.SetResult(null);
1222+
}
1223+
else
1224+
{
1225+
_networkPacketTaskSource.TrySetResult(null);
1226+
}
1227+
return TdsOperationStatus.InvalidData;
1228+
}
1229+
#endif
1230+
1231+
Debug.Assert(buff.IsEmpty || buff.Length >= len, "Invalid length sent to ReadByteArray()!");
1232+
1233+
// loop through and read up to array length
1234+
while (len > 0)
1235+
{
1236+
if ((_inBytesPacket == 0) || (_inBytesUsed == _inBytesRead))
1237+
{
1238+
TdsOperationStatus result = TryPrepareBuffer();
1239+
if (result != TdsOperationStatus.Done)
1240+
{
1241+
return result;
1242+
}
1243+
}
1244+
1245+
int bytesToRead = Math.Min(len, Math.Min(_inBytesPacket, _inBytesRead - _inBytesUsed));
1246+
Debug.Assert(bytesToRead > 0, "0 byte read in TryReadByteArray");
1247+
if (!buff.IsEmpty)
1248+
{
1249+
ReadOnlySpan<byte> copyFrom = new ReadOnlySpan<byte>(_inBuff, _inBytesUsed, bytesToRead);
1250+
Span<byte> copyTo = buff.Slice(totalRead, bytesToRead);
1251+
copyFrom.CopyTo(copyTo);
1252+
}
1253+
1254+
totalRead += bytesToRead;
1255+
_inBytesUsed += bytesToRead;
1256+
_inBytesPacket -= bytesToRead;
1257+
len -= bytesToRead;
1258+
1259+
AssertValidState();
1260+
}
1261+
1262+
return TdsOperationStatus.Done;
1263+
}
1264+
1265+
1266+
1267+
public TdsOperationStatus TryReadPlpByteArray(Span<byte> buff, int len, out int totalRead)
1268+
{
1269+
12091270
TdsParser.ReliabilitySection.Assert("unreliable call to ReadByteArray"); // you need to setup for a thread abort somewhere before you call this method
12101271
totalRead = 0;
12111272

@@ -1832,6 +1893,7 @@ internal int ReadPlpBytesChunk(byte[] buff, int offset, int len)
18321893
// Every time you call this method increment the offset and decrease len by the value of totalBytesRead
18331894
internal TdsOperationStatus TryReadPlpBytes(ref byte[] buff, int offset, int len, out int totalBytesRead)
18341895
{
1896+
totalBytesRead = 0;
18351897
int bytesRead;
18361898
int bytesLeft;
18371899
byte[] newbuf;
@@ -1898,11 +1960,10 @@ internal TdsOperationStatus TryReadPlpBytes(ref byte[] buff, int offset, int len
18981960
{
18991961
buff = new byte[_longlenleft];
19001962
}
1901-
1902-
totalBytesRead = 0;
1903-
1963+
bool stored = false;
19041964
while (bytesLeft > 0)
19051965
{
1966+
stored = false;
19061967
int bytesToRead = (int)Math.Min(_longlenleft, (ulong)bytesLeft);
19071968
if (buff.Length < (offset + bytesToRead))
19081969
{
@@ -1912,7 +1973,7 @@ internal TdsOperationStatus TryReadPlpBytes(ref byte[] buff, int offset, int len
19121973
buff = newbuf;
19131974
}
19141975

1915-
TdsOperationStatus result = TryReadByteArray(buff.AsSpan(offset), bytesToRead, out bytesRead);
1976+
TdsOperationStatus result = TryReadPlpByteArray(buff.AsSpan(offset), bytesToRead, out bytesRead);
19161977
Debug.Assert(bytesRead <= bytesLeft, "Read more bytes than we needed");
19171978
Debug.Assert((ulong)bytesRead <= _longlenleft, "Read more bytes than is available");
19181979

@@ -1937,7 +1998,8 @@ internal TdsOperationStatus TryReadPlpBytes(ref byte[] buff, int offset, int len
19371998
_snapshot._plpBuffer = buff;
19381999
if (_snapshotStatus != SnapshotStatus.NotActive && _snapshot.ContinueEnabled)
19392000
{
1940-
StoreProgress(this, bytesRead);
2001+
StoreReadPlpBytesProgress(this, bytesRead);
2002+
stored = true;
19412003
}
19422004
}
19432005
}
@@ -1948,9 +2010,10 @@ internal TdsOperationStatus TryReadPlpBytes(ref byte[] buff, int offset, int len
19482010
result = TryReadPlpLength(false, out _);
19492011
if (result != TdsOperationStatus.Done)
19502012
{
1951-
if (result == TdsOperationStatus.NeedMoreData && _snapshot != null && _snapshot.ContinueEnabled)
2013+
if (!stored && result == TdsOperationStatus.NeedMoreData && _snapshot != null && _snapshot.ContinueEnabled)
19522014
{
1953-
StoreProgress(this, bytesRead);
2015+
StoreReadPlpBytesProgress(this, bytesRead);
2016+
stored = true;
19542017
}
19552018
return result;
19562019
}
@@ -1964,15 +2027,12 @@ internal TdsOperationStatus TryReadPlpBytes(ref byte[] buff, int offset, int len
19642027
}
19652028
return TdsOperationStatus.Done;
19662029

1967-
static void StoreProgress(TdsParserStateObject stateObject, int size)
2030+
static void StoreReadPlpBytesProgress(TdsParserStateObject stateObject, int size)
19682031
{
1969-
if (stateObject._snapshot != null)
1970-
{
1971-
if (stateObject._snapshotStatus != SnapshotStatus.NotActive)
1972-
{
1973-
stateObject._snapshot.SetPacketPayloadSize(size);
1974-
}
1975-
}
2032+
Debug.Assert(stateObject._snapshot != null, "_snapshot must exist to store plp read progress");
2033+
Debug.Assert(stateObject._snapshotStatus != SnapshotStatus.NotActive, "_snapshot must be active to store plp read progress");
2034+
2035+
stateObject._snapshot.SetPacketPayloadSize(size);
19762036
}
19772037
}
19782038

@@ -2030,10 +2090,14 @@ internal TdsOperationStatus TryReadNetworkPacket()
20302090
if (_snapshotStatus != SnapshotStatus.NotActive)
20312091
{
20322092
#if DEBUG
2033-
// in debug builds stack traces contain line numbers so if we want to be
2034-
// able to compare the stack traces they must all be created in the same
2035-
// location in the code
2036-
string stackTrace = Environment.StackTrace;
2093+
string stackTrace = null;
2094+
if (s_checkNetworkPacketRetryStacks)
2095+
{
2096+
// in debug builds stack traces contain line numbers so if we want to be
2097+
// able to compare the stack traces they must all be created in the same
2098+
// location in the code
2099+
stackTrace = Environment.StackTrace;
2100+
}
20372101
#endif
20382102
if (_snapshot.MoveNext())
20392103
{
@@ -2045,22 +2109,21 @@ internal TdsOperationStatus TryReadNetworkPacket()
20452109
#endif
20462110
return TdsOperationStatus.Done;
20472111
}
2048-
#if DEBUG
20492112
else
20502113
{
2114+
#if DEBUG
20512115
if (s_checkNetworkPacketRetryStacks)
20522116
{
20532117
_lastStack = stackTrace;
20542118
}
2055-
2119+
#endif
20562120
if (_bTmpRead == 0 && _partialHeaderBytesRead == 0 && _longlenleft == 0 && _snapshot.ContinueEnabled)
20572121
{
20582122
// no temp between packets
20592123
// mark this point as continue-able
20602124
_snapshot.CaptureAsContinue(this);
20612125
}
20622126
}
2063-
#endif
20642127
}
20652128

20662129
// previous buffer is in snapshot
@@ -2933,11 +2996,12 @@ public bool ContinueEnabled
29332996
{
29342997
get
29352998
{
2936-
if (_continueSupported == null)
2937-
{
2938-
_continueSupported = AppContext.TryGetSwitch("Switch.Microsoft.Data.SqlClient.UseExperimentalAsyncContinue", out bool value) ? value : false;
2939-
}
2940-
return _continueSupported.Value;
2999+
//if (_continueSupported == null)
3000+
//{
3001+
// _continueSupported = AppContext.TryGetSwitch("Switch.Microsoft.Data.SqlClient.UseExperimentalAsyncContinue", out bool value) ? value : false;
3002+
//}
3003+
//return _continueSupported.Value;
3004+
return true;
29413005
}
29423006
}
29433007

@@ -3133,6 +3197,7 @@ private void ClearState()
31333197
_packetCounter = 0;
31343198
#endif
31353199
_stateObj = null;
3200+
//_continueSupported = null;
31363201
}
31373202
}
31383203
}

0 commit comments

Comments
 (0)