Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1970,7 +1970,7 @@ public StringBuilder Replace(string oldValue, string? newValue, int startIndex,

newValue ??= string.Empty;

int[]? replacements = null; // A list of replacement positions in a chunk to apply
Span<int> replacements = stackalloc int[5]; // A list of replacement positions in a chunk to apply
int replacementsCount = 0;

// Find the chunk, indexInChunk for the starting point
Expand All @@ -1985,13 +1985,11 @@ public StringBuilder Replace(string oldValue, string? newValue, int startIndex,
// Push it on the replacements array (with growth), we will do all replacements in a
// given chunk in one operation below (see ReplaceAllInChunk) so we don't have to slide
// many times.
if (replacements == null)
if (replacementsCount >= replacements.Length)
{
replacements = new int[5];
}
else if (replacementsCount >= replacements.Length)
{
Array.Resize(ref replacements, replacements.Length * 3 / 2 + 4); // Grow by ~1.5x, but more in the beginning
int[] tmp = new int[replacements.Length * 3 / 2 + 4]; // Grow by ~1.5x, but more in the beginning
replacements.CopyTo(tmp);
replacements = tmp;
}
replacements[replacementsCount++] = indexInChunk;
indexInChunk += oldValue.Length;
Expand All @@ -2009,8 +2007,7 @@ public StringBuilder Replace(string oldValue, string? newValue, int startIndex,
int index = indexInChunk + chunk.m_ChunkOffset;

// See if we accumulated any replacements, if so apply them.
Debug.Assert(replacements != null || replacementsCount == 0, "replacements was null and replacementsCount != 0");
ReplaceAllInChunk(replacements, replacementsCount, chunk, oldValue.Length, newValue);
ReplaceAllInChunk(replacements.Slice(0, replacementsCount), chunk, oldValue.Length, newValue);
// The replacement has affected the logical index. Adjust it.
index += ((newValue.Length - oldValue.Length) * replacementsCount);
replacementsCount = 0;
Expand Down Expand Up @@ -2162,16 +2159,15 @@ private unsafe void Insert(int index, char* value, int valueCount)
/// Replaces strings at specified indices with a new string in a chunk.
/// </summary>
/// <param name="replacements">The list of indices, relative to the beginning of the chunk, to remove at.</param>
/// <param name="replacementsCount">The number of replacements to make.</param>
/// <param name="sourceChunk">The source chunk.</param>
/// <param name="removeCount">The number of characters to remove at each replacement.</param>
/// <param name="value">The string to insert at each replacement.</param>
/// <remarks>
/// This routine is very efficient because it does replacements in bulk.
/// </remarks>
private void ReplaceAllInChunk(int[]? replacements, int replacementsCount, StringBuilder sourceChunk, int removeCount, string value)
private void ReplaceAllInChunk(ReadOnlySpan<int> replacements, StringBuilder sourceChunk, int removeCount, string value)
{
if (replacementsCount <= 0)
if (replacements.IsEmpty)
{
return;
}
Expand All @@ -2180,9 +2176,8 @@ private void ReplaceAllInChunk(int[]? replacements, int replacementsCount, Strin
{
fixed (char* valuePtr = value)
{
Debug.Assert(replacements != null, "replacements was null when replacementsCount > 0");
// calculate the total amount of extra space or space needed for all the replacements.
long longDelta = (value.Length - removeCount) * (long)replacementsCount;
long longDelta = (value.Length - removeCount) * (long)replacements.Length;
int delta = (int)longDelta;
if (delta != longDelta)
{
Expand All @@ -2206,7 +2201,7 @@ private void ReplaceAllInChunk(int[]? replacements, int replacementsCount, Strin
ReplaceInPlaceAtChunk(ref targetChunk!, ref targetIndexInChunk, valuePtr, value.Length);
int gapStart = replacements[i] + removeCount;
i++;
if (i >= replacementsCount)
if ((uint)i >= replacements.Length)
{
break;
}
Expand Down