Skip to content

Commit

Permalink
Optimize glob matching logic (#296)
Browse files Browse the repository at this point in the history
* Optimize glob matching by using ASCII comparisons instead of culture-sensitive

* Revert braces

* Fix EOL

* Check if uppercase ASCII before lowering

* Handle negstive

---------

Co-authored-by: Lukas Maas <lumaas@microsoft.com>
  • Loading branch information
PaulusParssinen and lmaas authored Apr 23, 2024
1 parent d4c89fd commit 4d37ca7
Showing 1 changed file with 25 additions and 20 deletions.
45 changes: 25 additions & 20 deletions libs/server/GlobUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ namespace Garnet.server
public static class GlobUtils
{
/// <summary>
/// Glob-style pattern matching
/// Glob-style ASCII pattern matching
/// </summary>
/// <returns>Whether match was found</returns>
public static unsafe bool Match(byte* pattern, int patternLen, byte* key, int stringLen, bool nocase = false)
public static unsafe bool Match(byte* pattern, int patternLen, byte* key, int stringLen, bool ignoreCase = false)
{
static byte ToLowerAscii(byte value)
{
if ((uint)(value - 'A') <= (uint)('Z' - 'A')) // Is in [A-Z]
value = (byte)(value | 0x20);
return value;
}

while (patternLen > 0 && stringLen > 0)
{
switch (pattern[0])
Expand All @@ -28,7 +35,7 @@ public static unsafe bool Match(byte* pattern, int patternLen, byte* key, int st
return true; /* match */
while (stringLen > 0)
{
if (Match(pattern + 1, patternLen - 1, key, stringLen, nocase))
if (Match(pattern + 1, patternLen - 1, key, stringLen, ignoreCase))
return true; /* match */
key++;
stringLen--;
Expand All @@ -42,16 +49,15 @@ public static unsafe bool Match(byte* pattern, int patternLen, byte* key, int st

case (byte)'[':
{
bool not, match;
pattern++;
patternLen--;
not = (pattern[0] == '^');
var not = pattern[0] == '^';
if (not)
{
pattern++;
patternLen--;
}
match = false;
var match = false;
while (true)
{
if (pattern[0] == '\\' && patternLen >= 2)
Expand All @@ -73,20 +79,19 @@ public static unsafe bool Match(byte* pattern, int patternLen, byte* key, int st
}
else if (patternLen >= 3 && pattern[1] == '-')
{
int start = pattern[0];
int end = pattern[2];
int c = key[0];
byte start = pattern[0];
byte end = pattern[2];
byte c = key[0];
if (start > end)
{
int t = start;
start = end;
end = t;
(end, start) = (start, end);
}
if (nocase)

if (ignoreCase)
{
start = char.ToLower((char)start);
end = char.ToLower((char)end);
c = char.ToLower((char)c);
start = ToLowerAscii(start);
end = ToLowerAscii(end);
c = ToLowerAscii(c);
}
pattern += 2;
patternLen -= 2;
Expand All @@ -95,14 +100,14 @@ public static unsafe bool Match(byte* pattern, int patternLen, byte* key, int st
}
else
{
if (!nocase)
if (!ignoreCase)
{
if (pattern[0] == key[0])
match = true;
}
else
{
if (char.ToLower((char)pattern[0]) == char.ToLower((char)key[0]))
if (ToLowerAscii(pattern[0]) == ToLowerAscii(key[0]))
match = true;
}
}
Expand All @@ -129,14 +134,14 @@ public static unsafe bool Match(byte* pattern, int patternLen, byte* key, int st

/* fall through */
default:
if (!nocase)
if (!ignoreCase)
{
if (pattern[0] != key[0])
return false; /* no match */
}
else
{
if (char.ToLower((char)pattern[0]) != char.ToLower((char)key[0]))
if (ToLowerAscii(pattern[0]) != ToLowerAscii(key[0]))
return false; /* no match */
}
key++;
Expand Down

0 comments on commit 4d37ca7

Please sign in to comment.