Skip to content

Commit 4be5d94

Browse files
committed
Refactor test mirror logic for stream position accuracy
Refactor test helpers to use out instead of ref for dataCopyArrayPosition, ensuring the mirror array always matches the current stream position after writes. Update mirror logic to copy written bytes to the correct position and zero-fill or clear regions as needed when the stream length changes. Simplify comments and improve consistency of test verification.
1 parent 917b98f commit 4be5d94

1 file changed

Lines changed: 74 additions & 55 deletions

File tree

Source/Tst/Shared/KZDev.PerfUtils.MemoryStreamSlim.Tests.Shared/UsingMemoryStreamSlim.ReadWrite.cs

Lines changed: 74 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,15 +1368,15 @@ public void UsingMemoryStreamSlim_WriteWithChaos_WritesCorrectData ()
13681368
switch (GetTestInteger() % 6)
13691369
{
13701370
case 0:
1371-
WriteArrayDataToStream(testService, dataCopy, ref dataCopyIndexPosition);
1371+
WriteArrayDataToStream(testService, dataCopy, out dataCopyIndexPosition);
13721372
break;
13731373

13741374
case 1:
1375-
WriteSpanDataToStream(testService, dataCopy, ref dataCopyIndexPosition);
1375+
WriteSpanDataToStream(testService, dataCopy, out dataCopyIndexPosition);
13761376
break;
13771377

13781378
case 2:
1379-
WriteByteDataToStream(testService, dataCopy, ref dataCopyIndexPosition);
1379+
WriteByteDataToStream(testService, dataCopy, out dataCopyIndexPosition);
13801380
break;
13811381

13821382
case 3:
@@ -1392,44 +1392,56 @@ public void UsingMemoryStreamSlim_WriteWithChaos_WritesCorrectData ()
13921392
break;
13931393
}
13941394
}
1395-
// Verify the contents
1396-
testService.SetLength(Math.Max(testService.Length, dataCopy.Length));
1395+
// Verify the contents: SetLength extension zero-fills new bytes; mirror must match.
1396+
long streamLengthBeforeFinalResize = testService.Length;
1397+
testService.SetLength(Math.Max(streamLengthBeforeFinalResize, dataCopy.Length));
1398+
long streamLengthAfterFinalResize = testService.Length;
1399+
if (streamLengthAfterFinalResize > streamLengthBeforeFinalResize)
1400+
{
1401+
int clearStartIndex = checked((int)streamLengthBeforeFinalResize);
1402+
int clearLength = checked((int)(streamLengthAfterFinalResize - streamLengthBeforeFinalResize));
1403+
Array.Clear(dataCopy, clearStartIndex, clearLength);
1404+
}
13971405
VerifyContentsFromStartToEndOneRead(testService, dataCopy);
13981406
}
13991407

1400-
void WriteArrayDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, ref int dataCopyArrayPosition)
1408+
void WriteArrayDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, out int dataCopyArrayPosition)
14011409
{
14021410
int writePosition = (int)stream.Position;
14031411
int spaceLeft = dataCopyArray.Length - writePosition;
14041412
int byteCount = (spaceLeft < 10) ? spaceLeft : RandomSource.GetRandomInteger(1, spaceLeft / 2);
14051413
byte[] writeData = MemoryTestPrep.GetRandomByteArray(byteCount);
14061414

14071415
stream.Write(writeData);
1408-
Array.Copy(writeData, 0, dataCopyArray, dataCopyArrayPosition, byteCount);
1409-
dataCopyArrayPosition += byteCount;
1416+
Array.Copy(writeData, 0, dataCopyArray, writePosition, byteCount);
1417+
dataCopyArrayPosition = writePosition + byteCount;
14101418
}
14111419

1412-
void WriteSpanDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, ref int dataCopyArrayPosition)
1420+
void WriteSpanDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, out int dataCopyArrayPosition)
14131421
{
14141422
int writePosition = (int)stream.Position;
14151423
int spaceLeft = dataCopyArray.Length - writePosition;
14161424
int byteCount = (spaceLeft < 10) ? spaceLeft : RandomSource.GetRandomInteger(1, spaceLeft / 2);
14171425
byte[] writeData = MemoryTestPrep.GetRandomByteArray(byteCount);
14181426

14191427
stream.Write(writeData.AsSpan());
1420-
Array.Copy(writeData, 0, dataCopyArray, dataCopyArrayPosition, byteCount);
1421-
dataCopyArrayPosition += byteCount;
1428+
Array.Copy(writeData, 0, dataCopyArray, writePosition, byteCount);
1429+
dataCopyArrayPosition = writePosition + byteCount;
14221430
}
14231431

1424-
void WriteByteDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, ref int dataCopyArrayPosition)
1432+
void WriteByteDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, out int dataCopyArrayPosition)
14251433
{
14261434
int writePosition = (int)stream.Position;
14271435
int spaceLeft = dataCopyArray.Length - writePosition;
14281436
if (spaceLeft < 1)
1437+
{
1438+
dataCopyArrayPosition = writePosition;
14291439
return;
1440+
}
14301441
byte writeData = GetRandomByte();
14311442
stream.WriteByte(writeData);
1432-
dataCopyArray[dataCopyArrayPosition++] = writeData;
1443+
dataCopyArray[writePosition] = writeData;
1444+
dataCopyArrayPosition = writePosition + 1;
14331445
}
14341446

14351447
void PositionStream (MemoryStreamSlim stream, int maxPosition, out int dataCopyArrayPosition)
@@ -1482,8 +1494,8 @@ void SetStreamLength (MemoryStreamSlim stream, int maxPosition, byte[] dataCopyA
14821494
int currentLength = (int)stream.Length;
14831495
int newLength = (maxPosition < 2) ? maxPosition : RandomSource.GetRandomInteger(2, maxPosition);
14841496

1485-
// Do we need to clear data in the copy?
1486-
if ((stream.Mode == MemoryStreamSlimMode.Dynamic) && (newLength < currentLength))
1497+
// Discarded logical bytes are unreadable from the stream; clear the mirror for any mode.
1498+
if (newLength < currentLength)
14871499
{
14881500
Array.Clear(dataCopyArray, newLength, currentLength - newLength);
14891501
}
@@ -1529,15 +1541,15 @@ public async Task UsingMemoryStreamSlim_WriteWithChaos_OnManyThreads_WritesCorre
15291541
switch (GetTestInteger() % 6)
15301542
{
15311543
case 0:
1532-
WriteArrayDataToStream(testService, dataCopy, ref dataCopyIndexPosition);
1544+
WriteArrayDataToStream(testService, dataCopy, out dataCopyIndexPosition);
15331545
break;
15341546

15351547
case 1:
1536-
WriteSpanDataToStream(testService, dataCopy, ref dataCopyIndexPosition);
1548+
WriteSpanDataToStream(testService, dataCopy, out dataCopyIndexPosition);
15371549
break;
15381550

15391551
case 2:
1540-
WriteByteDataToStream(testService, dataCopy, ref dataCopyIndexPosition);
1552+
WriteByteDataToStream(testService, dataCopy, out dataCopyIndexPosition);
15411553
break;
15421554

15431555
case 3:
@@ -1553,48 +1565,60 @@ public async Task UsingMemoryStreamSlim_WriteWithChaos_OnManyThreads_WritesCorre
15531565
break;
15541566
}
15551567
}
1556-
// Verify the contents
1557-
testService.SetLength(Math.Max(testService.Length, dataCopy.Length));
1568+
// Verify the contents: SetLength extension zero-fills new bytes; mirror must match.
1569+
long streamLengthBeforeFinalResize = testService.Length;
1570+
testService.SetLength(Math.Max(streamLengthBeforeFinalResize, dataCopy.Length));
1571+
long streamLengthAfterFinalResize = testService.Length;
1572+
if (streamLengthAfterFinalResize > streamLengthBeforeFinalResize)
1573+
{
1574+
int clearStartIndex = checked((int)streamLengthBeforeFinalResize);
1575+
int clearLength = checked((int)(streamLengthAfterFinalResize - streamLengthBeforeFinalResize));
1576+
Array.Clear(dataCopy, clearStartIndex, clearLength);
1577+
}
15581578
// Alternate how we verify the data
15591579
if (0 == (testLoop & 1))
15601580
await VerifyContentsFromStartToEndOneReadAsync(testService, dataCopy);
15611581
else
15621582
await VerifyContentsFromStartToEndInBlocksAsync(testService, dataCopy, 0x61);
15631583
}
15641584

1565-
void WriteArrayDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, ref int dataCopyArrayPosition)
1585+
void WriteArrayDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, out int dataCopyArrayPosition)
15661586
{
15671587
int writePosition = (int)stream.Position;
15681588
int spaceLeft = dataCopyArray.Length - writePosition;
15691589
int byteCount = (spaceLeft < 10) ? spaceLeft : RandomSource.GetRandomInteger(1, spaceLeft / 2);
15701590
byte[] writeData = MemoryTestPrep.GetRandomByteArray(byteCount);
15711591

15721592
stream.Write(writeData);
1573-
Array.Copy(writeData, 0, dataCopyArray, dataCopyArrayPosition, byteCount);
1574-
dataCopyArrayPosition += byteCount;
1593+
Array.Copy(writeData, 0, dataCopyArray, writePosition, byteCount);
1594+
dataCopyArrayPosition = writePosition + byteCount;
15751595
}
15761596

1577-
void WriteSpanDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, ref int dataCopyArrayPosition)
1597+
void WriteSpanDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, out int dataCopyArrayPosition)
15781598
{
15791599
int writePosition = (int)stream.Position;
15801600
int spaceLeft = dataCopyArray.Length - writePosition;
15811601
int byteCount = (spaceLeft < 10) ? spaceLeft : RandomSource.GetRandomInteger(1, spaceLeft / 2);
15821602
byte[] writeData = MemoryTestPrep.GetRandomByteArray(byteCount);
15831603

15841604
stream.Write(writeData.AsSpan());
1585-
Array.Copy(writeData, 0, dataCopyArray, dataCopyArrayPosition, byteCount);
1586-
dataCopyArrayPosition += byteCount;
1605+
Array.Copy(writeData, 0, dataCopyArray, writePosition, byteCount);
1606+
dataCopyArrayPosition = writePosition + byteCount;
15871607
}
15881608

1589-
void WriteByteDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, ref int dataCopyArrayPosition)
1609+
void WriteByteDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, out int dataCopyArrayPosition)
15901610
{
15911611
int writePosition = (int)stream.Position;
15921612
int spaceLeft = dataCopyArray.Length - writePosition;
15931613
if (spaceLeft < 1)
1614+
{
1615+
dataCopyArrayPosition = writePosition;
15941616
return;
1617+
}
15951618
byte writeData = GetRandomByte();
15961619
stream.WriteByte(writeData);
1597-
dataCopyArray[dataCopyArrayPosition++] = writeData;
1620+
dataCopyArray[writePosition] = writeData;
1621+
dataCopyArrayPosition = writePosition + 1;
15981622
}
15991623

16001624
void PositionStream (MemoryStreamSlim stream, int maxPosition, out int dataCopyArrayPosition)
@@ -1647,8 +1671,8 @@ void SetStreamLength (MemoryStreamSlim stream, int maxPosition, byte[] dataCopyA
16471671
int currentLength = (int)stream.Length;
16481672
int newLength = (maxPosition < 2) ? maxPosition : RandomSource.GetRandomInteger(2, maxPosition);
16491673

1650-
// Do we need to clear data in the copy?
1651-
if ((stream.Mode == MemoryStreamSlimMode.Dynamic) && (newLength < currentLength))
1674+
// Discarded logical bytes are unreadable from the stream; clear the mirror for any mode.
1675+
if (newLength < currentLength)
16521676
{
16531677
Array.Clear(dataCopyArray, newLength, currentLength - newLength);
16541678
}
@@ -1724,15 +1748,15 @@ public void UsingMemoryStreamSlim_WriteWithChaos_DeterministicOperationCycle_Wri
17241748
switch (chaosIndex % 5)
17251749
{
17261750
case 0:
1727-
WriteArrayDataToStream(testService, dataCopy, testSegmentSize, ref dataCopyIndexPosition);
1751+
WriteArrayDataToStream(testService, dataCopy, testSegmentSize, out dataCopyIndexPosition);
17281752
break;
17291753

17301754
case 1:
1731-
WriteSpanDataToStream(testService, dataCopy, testSegmentSize, ref dataCopyIndexPosition);
1755+
WriteSpanDataToStream(testService, dataCopy, testSegmentSize, out dataCopyIndexPosition);
17321756
break;
17331757

17341758
case 2:
1735-
WriteByteDataToStream(testService, dataCopy, ref dataCopyIndexPosition);
1759+
WriteByteDataToStream(testService, dataCopy, out dataCopyIndexPosition);
17361760
break;
17371761

17381762
case 3:
@@ -1750,45 +1774,38 @@ public void UsingMemoryStreamSlim_WriteWithChaos_DeterministicOperationCycle_Wri
17501774
}
17511775

17521776
void WriteArrayDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, int segmentSizeCap,
1753-
ref int dataCopyArrayPosition)
1777+
out int dataCopyArrayPosition)
17541778
{
17551779
int writePosition = (int)stream.Position;
17561780
int spaceLeft = dataCopyArray.Length - writePosition;
17571781
int writeByteCount = ResolveChaosWriteByteCount(spaceLeft, segmentSizeCap);
17581782
byte[] writeData = MemoryTestPrep.GetRandomByteArray(writeByteCount);
17591783

17601784
stream.Write(writeData);
1761-
Array.Copy(writeData, 0, dataCopyArray, dataCopyArrayPosition, writeByteCount);
1762-
dataCopyArrayPosition += writeByteCount;
1785+
Array.Copy(writeData, 0, dataCopyArray, writePosition, writeByteCount);
1786+
dataCopyArrayPosition = writePosition + writeByteCount;
17631787
}
17641788

17651789
void WriteSpanDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, int segmentSizeCap,
1766-
ref int dataCopyArrayPosition)
1790+
out int dataCopyArrayPosition)
17671791
{
17681792
int writePosition = (int)stream.Position;
17691793
int spaceLeft = dataCopyArray.Length - writePosition;
17701794
int writeByteCount = ResolveChaosWriteByteCount(spaceLeft, segmentSizeCap);
17711795
byte[] writeData = MemoryTestPrep.GetRandomByteArray(writeByteCount);
17721796

17731797
stream.Write(writeData.AsSpan());
1774-
Array.Copy(writeData, 0, dataCopyArray, dataCopyArrayPosition, writeByteCount);
1775-
dataCopyArrayPosition += writeByteCount;
1798+
Array.Copy(writeData, 0, dataCopyArray, writePosition, writeByteCount);
1799+
dataCopyArrayPosition = writePosition + writeByteCount;
17761800
}
17771801

1778-
/// <summary>
1779-
/// Picks a write size for chaos array/span writes: small tail flushes use all remaining space;
1780-
/// otherwise the exclusive upper bound is the smaller of half the space left and one past the
1781-
/// segment cap (matching <see cref="MemoryTestPrep.FillStreamAndArrayWithRandomBytes(Stream, int, int)"/> chunking).
1782-
/// </summary>
1783-
/// <param name="spaceLeft">
1784-
/// Bytes from the stream position to the end of the logical buffer.
1785-
/// </param>
1786-
/// <param name="segmentSizeCap">
1787-
/// Maximum bytes per write for this outer loop iteration.
1788-
/// </param>
1789-
/// <returns>
1790-
/// The number of bytes to write.
1791-
/// </returns>
1802+
// Local helper (XML docs are not valid on local functions for tooling). Picks a write size for
1803+
// chaos array/span writes: small tail flushes use all remaining space; otherwise the exclusive
1804+
// upper bound is the smaller of half the space left and one past the segment cap (matching
1805+
// MemoryTestPrep.FillStreamAndArrayWithRandomBytes chunking).
1806+
// spaceLeft: bytes from the stream position to the end of the logical buffer.
1807+
// segmentSizeCap: maximum bytes per write for this outer loop iteration.
1808+
// Returns the number of bytes to write.
17921809
int ResolveChaosWriteByteCount (int spaceLeft, int segmentSizeCap)
17931810
{
17941811
if (spaceLeft < 10)
@@ -1802,18 +1819,20 @@ int ResolveChaosWriteByteCount (int spaceLeft, int segmentSizeCap)
18021819
return RandomSource.GetRandomInteger(1, writeMaxExclusive);
18031820
}
18041821

1805-
void WriteByteDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, ref int dataCopyArrayPosition)
1822+
void WriteByteDataToStream (MemoryStreamSlim stream, byte[] dataCopyArray, out int dataCopyArrayPosition)
18061823
{
18071824
int writePosition = (int)stream.Position;
18081825
int spaceLeft = dataCopyArray.Length - writePosition;
18091826
if (spaceLeft < 1)
18101827
{
1828+
dataCopyArrayPosition = writePosition;
18111829
return;
18121830
}
18131831

18141832
byte writeData = GetRandomByte();
18151833
stream.WriteByte(writeData);
1816-
dataCopyArray[dataCopyArrayPosition++] = writeData;
1834+
dataCopyArray[writePosition] = writeData;
1835+
dataCopyArrayPosition = writePosition + 1;
18171836
}
18181837

18191838
void PositionStream (MemoryStreamSlim stream, int maxPosition, out int dataCopyArrayPosition)

0 commit comments

Comments
 (0)