Skip to content

Commit 05ebdcf

Browse files
committed
Cleaned span based version
1 parent ed2afaf commit 05ebdcf

File tree

1 file changed

+40
-42
lines changed

1 file changed

+40
-42
lines changed

src/Http/Http/src/Features/QueryFeature.cs

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using System.Runtime.Intrinsics;
99
using System.Runtime.Intrinsics.X86;
1010
using Microsoft.AspNetCore.Internal;
11-
using Microsoft.AspNetCore.WebUtilities;
1211
using Microsoft.Extensions.Primitives;
1312

1413
namespace Microsoft.AspNetCore.Http.Features
@@ -122,7 +121,7 @@ public IQueryCollection Query
122121
}
123122

124123
KvpAccumulator accumulator = new();
125-
int queryStringLength = queryString.Length;
124+
var queryStringLength = queryString.Length;
126125

127126
char[]? arryToReturnToPool = null;
128127
Span<char> query = (queryStringLength <= 128
@@ -139,17 +138,17 @@ public IQueryCollection Query
139138

140139
while (!query.IsEmpty)
141140
{
142-
int delimiterIndex = query.IndexOf('&');
141+
var delimiterIndex = query.IndexOf('&');
143142

144-
Span<char> querySegment = delimiterIndex >= 0
143+
var querySegment = delimiterIndex >= 0
145144
? query.Slice(0, delimiterIndex)
146145
: query;
147146

148-
int equalIndex = querySegment.IndexOf('=');
147+
var equalIndex = querySegment.IndexOf('=');
149148

150149
if (equalIndex >= 0)
151150
{
152-
int i = 0;
151+
var i = 0;
153152
for (; i < querySegment.Length; ++i)
154153
{
155154
if (!char.IsWhiteSpace(querySegment[i]))
@@ -158,11 +157,11 @@ public IQueryCollection Query
158157
}
159158
}
160159

161-
Span<char> name = querySegment[i..equalIndex];
162-
Span<char> value = querySegment.Slice(equalIndex + 1);
160+
var name = querySegment[i..equalIndex];
161+
var value = querySegment.Slice(equalIndex + 1);
163162

164-
name.ReplacePlusWithSpaceInPlace();
165-
value.ReplacePlusWithSpaceInPlace();
163+
SpanHelper.ReplacePlusWithSpaceInPlace(name);
164+
SpanHelper.ReplacePlusWithSpaceInPlace(value);
166165

167166
accumulator.Append(
168167
Uri.UnescapeDataString(name.ToString()),
@@ -212,13 +211,12 @@ public void Append(ReadOnlySpan<char> key, ReadOnlySpan<char> value = default)
212211
/// </summary>
213212
public void Append(string key, string value)
214213
{
215-
if (_accumulator == null)
214+
if (_accumulator is null)
216215
{
217216
_accumulator = new AdaptiveCapacityDictionary<string, StringValues>(StringComparer.OrdinalIgnoreCase);
218217
}
219218

220-
StringValues values;
221-
if (_accumulator.TryGetValue(key, out values))
219+
if (_accumulator.TryGetValue(key, out var values))
222220
{
223221
if (values.Count == 0)
224222
{
@@ -232,9 +230,9 @@ public void Append(string key, string value)
232230
else
233231
{
234232
// Add zero count entry and move to data to expanding list dictionary
235-
_accumulator[key] = default(StringValues);
233+
_accumulator[key] = default;
236234

237-
if (_expandingAccumulator == null)
235+
if (_expandingAccumulator is null)
238236
{
239237
_expandingAccumulator = new AdaptiveCapacityDictionary<string, List<string>>(5, StringComparer.OrdinalIgnoreCase);
240238
}
@@ -293,44 +291,44 @@ public AdaptiveCapacityDictionary<string, StringValues> GetResults()
293291
return _accumulator ?? new AdaptiveCapacityDictionary<string, StringValues>(0, StringComparer.OrdinalIgnoreCase);
294292
}
295293
}
296-
}
297-
298-
internal static class MySpanExtensions
299-
{
300-
public static void ReplacePlusWithSpaceInPlace(this Span<char> span)
301-
=> ReplaceInPlace(span, '+', ' ');
302294

303-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
304-
public static unsafe void ReplaceInPlace(this Span<char> span, char oldChar, char newChar)
295+
private static class SpanHelper
305296
{
306-
nint i = 0;
307-
nint n = (nint)(uint)span.Length;
297+
public static void ReplacePlusWithSpaceInPlace(Span<char> span)
298+
=> ReplaceInPlace(span, '+', ' ');
308299

309-
fixed (char* ptr = span)
300+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
301+
public static unsafe void ReplaceInPlace(Span<char> span, char oldChar, char newChar)
310302
{
311-
ushort* pVec = (ushort*)ptr;
303+
var i = (nint)0;
304+
var n = (nint)(uint)span.Length;
312305

313-
if (Sse41.IsSupported && n >= Vector128<ushort>.Count)
306+
fixed (char* ptr = span)
314307
{
315-
Vector128<ushort> vecOldChar = Vector128.Create((ushort)oldChar);
316-
Vector128<ushort> vecNewChar = Vector128.Create((ushort)newChar);
308+
var pVec = (ushort*)ptr;
317309

318-
do
310+
if (Sse41.IsSupported && n >= Vector128<ushort>.Count)
319311
{
320-
Vector128<ushort> vec = Sse2.LoadVector128(pVec + i);
321-
Vector128<ushort> mask = Sse2.CompareEqual(vec, vecOldChar);
322-
Vector128<ushort> res = Sse41.BlendVariable(vec, vecNewChar, mask);
323-
Sse2.Store(pVec + i, res);
312+
var vecOldChar = Vector128.Create((ushort)oldChar);
313+
var vecNewChar = Vector128.Create((ushort)newChar);
324314

325-
i += Vector128<ushort>.Count;
326-
} while (i <= n - Vector128<ushort>.Count);
327-
}
315+
do
316+
{
317+
var vec = Sse2.LoadVector128(pVec + i);
318+
var mask = Sse2.CompareEqual(vec, vecOldChar);
319+
var res = Sse41.BlendVariable(vec, vecNewChar, mask);
320+
Sse2.Store(pVec + i, res);
328321

329-
for (; i < n; ++i)
330-
{
331-
if (ptr[i] == oldChar)
322+
i += Vector128<ushort>.Count;
323+
} while (i <= n - Vector128<ushort>.Count);
324+
}
325+
326+
for (; i < n; ++i)
332327
{
333-
ptr[i] = newChar;
328+
if (ptr[i] == oldChar)
329+
{
330+
ptr[i] = newChar;
331+
}
334332
}
335333
}
336334
}

0 commit comments

Comments
 (0)