-
Notifications
You must be signed in to change notification settings - Fork 550
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove misc. temporary allocations from RESP parsing (#431)
* Add TrySliceWithLengthHeader to RespReadUtils * Will lay ground work for more allocation-free code * wip: Start removing allocations. * ReadByteArray => TrySlice * Avoid some temp arrays in strings I came across * Move Ascii operations to AsciiUtils and use vectorized BCL where possible * Remove LINQ From ListRemove * Remove LINQ From ListInsert * quick fix to check if ci is green * Fix ListRemove regression * Remove unused variable left from previous commits * More SortedSet to new methods * Use slice in AdminCommands * Remove more misc. tiny allocations * Remove more misc. tiny allocations * Simplify more RESP parsing.. * Little number parsing consolidation to NumUtils * Revert some places where no benefit and add some more * Revert couple more for now * Apply PR feedback * and remove couple unnecessary unsafe modifiers * Apply PR feedback * oops, forgot this --------- Co-authored-by: Badrish Chandramouli <[email protected]>
- Loading branch information
1 parent
a7077a1
commit d15c5a8
Showing
38 changed files
with
494 additions
and
517 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,87 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using System; | ||
using System.Diagnostics; | ||
using System.Text; | ||
|
||
namespace Garnet.common; | ||
|
||
/// <summary> | ||
/// Utilites for ASCII parsing and manipulation. | ||
/// </summary> | ||
/// <remarks> | ||
/// This class polyfills various <see cref="char"/> and <c>Ascii</c> methods for .NET 6. | ||
/// </remarks> | ||
public static class AsciiUtils | ||
{ | ||
public static byte ToLower(byte value) | ||
/// <summary>Indicates whether a character is within the specified inclusive range.</summary> | ||
/// <param name="c">The character to evaluate.</param> | ||
/// <param name="minInclusive">The lower bound, inclusive.</param> | ||
/// <param name="maxInclusive">The upper bound, inclusive.</param> | ||
/// <returns>true if <paramref name="c"/> is within the specified range; otherwise, false.</returns> | ||
/// <remarks> | ||
/// The method does not validate that <paramref name="maxInclusive"/> is greater than or equal | ||
/// to <paramref name="minInclusive"/>. If <paramref name="maxInclusive"/> is less than | ||
/// <paramref name="minInclusive"/>, the behavior is undefined. | ||
/// </remarks> | ||
public static bool IsBetween(byte c, char minInclusive, char maxInclusive) | ||
{ | ||
return (uint)(c - minInclusive) <= (uint)(maxInclusive - minInclusive); | ||
} | ||
|
||
public static byte ToLower(byte c) | ||
{ | ||
if ((uint)(value - 'A') <= (uint)('Z' - 'A')) // Is in [A-Z] | ||
value = (byte)(value | 0x20); | ||
return value; | ||
if (IsBetween(c, 'A', 'Z')) | ||
c = (byte)(c | 0x20); | ||
return c; | ||
} | ||
public static byte ToUpper(byte c) | ||
{ | ||
if (IsBetween(c, 'a', 'z')) | ||
c = (byte)(c & ~0x20); | ||
return c; | ||
} | ||
|
||
/// <summary> | ||
/// Convert ASCII Span to upper case | ||
/// </summary> | ||
public static void ToUpperInPlace(Span<byte> command) | ||
{ | ||
#if NET8_0_OR_GREATER | ||
Ascii.ToUpperInPlace(command, out _); | ||
#else | ||
foreach (ref var c in command) | ||
if (c > 96 && c < 123) | ||
c -= 32; | ||
#endif | ||
} | ||
|
||
/// <inheritdoc cref="EqualsUpperCaseSpanIgnoringCase(ReadOnlySpan{byte}, ReadOnlySpan{byte})"/> | ||
public static bool EqualsUpperCaseSpanIgnoringCase(this Span<byte> left, ReadOnlySpan<byte> right) | ||
=> EqualsUpperCaseSpanIgnoringCase(left, right); | ||
|
||
/// <summary> | ||
/// Check if two byte spans are equal, where right is an all-upper-case span, ignoring case if there are ASCII bytes. | ||
/// </summary> | ||
public static bool EqualsUpperCaseSpanIgnoringCase(this ReadOnlySpan<byte> left, ReadOnlySpan<byte> right) | ||
{ | ||
if (left.SequenceEqual(right)) | ||
return true; | ||
if (left.Length != right.Length) | ||
return false; | ||
for (int i = 0; i < left.Length; i++) | ||
{ | ||
var b1 = left[i]; | ||
var b2 = right[i]; | ||
|
||
// Debug assert that b2 is an upper case letter 'A'-'Z' | ||
Debug.Assert(b2 is >= 65 and <= 90); | ||
|
||
if (b1 == b2 || b1 - 32 == b2) | ||
continue; | ||
return false; | ||
} | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.