perf: reduce SubList token string churn
This commit is contained in:
@@ -362,9 +362,9 @@ public sealed class SubList : IDisposable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var key = token.ToString();
|
if (!TryGetLiteralNode(level, token, out _, out node))
|
||||||
if (!level.Nodes.TryGetValue(key, out node))
|
|
||||||
{
|
{
|
||||||
|
var key = token.ToString();
|
||||||
node = new TrieNode();
|
node = new TrieNode();
|
||||||
level.Nodes[key] = node;
|
level.Nodes[key] = node;
|
||||||
}
|
}
|
||||||
@@ -474,13 +474,20 @@ public sealed class SubList : IDisposable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
level.Nodes.TryGetValue(token.ToString(), out node);
|
if (!TryGetLiteralNode(level, token, out var existingToken, out node))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pathList.Add((level, node, existingToken, isPwc: false, isFwc: false));
|
||||||
|
if (node.Next == null)
|
||||||
|
return false; // corrupted trie state
|
||||||
|
level = node.Next;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node == null)
|
if (node == null)
|
||||||
return false; // not found
|
return false; // not found
|
||||||
|
|
||||||
var tokenStr = token.ToString();
|
var tokenStr = isPwc ? "*" : ">";
|
||||||
pathList.Add((level, node, tokenStr, isPwc, isFwc));
|
pathList.Add((level, node, tokenStr, isPwc, isFwc));
|
||||||
if (node.Next == null)
|
if (node.Next == null)
|
||||||
return false; // corrupted trie state
|
return false; // corrupted trie state
|
||||||
@@ -652,6 +659,23 @@ public sealed class SubList : IDisposable
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool TryGetLiteralNode(TrieLevel level, ReadOnlySpan<char> token, out string existingToken, out TrieNode node)
|
||||||
|
{
|
||||||
|
foreach (var (candidate, existingNode) in level.Nodes)
|
||||||
|
{
|
||||||
|
if (!SubjectMatch.TokenEquals(token, candidate))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
existingToken = candidate;
|
||||||
|
node = existingNode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
existingToken = string.Empty;
|
||||||
|
node = null!;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private bool HasExactQueueInterestNoLock(string subject, string queue)
|
private bool HasExactQueueInterestNoLock(string subject, string queue)
|
||||||
{
|
{
|
||||||
var subs = new List<Subscription>();
|
var subs = new List<Subscription>();
|
||||||
|
|||||||
@@ -249,6 +249,9 @@ public static class SubjectMatch
|
|||||||
return tokens.Count == test.Count;
|
return tokens.Count == test.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool TokenEquals(ReadOnlySpan<char> token, string candidate)
|
||||||
|
=> token.SequenceEqual(candidate);
|
||||||
|
|
||||||
private static bool TokensCanMatch(ReadOnlySpan<char> t1, ReadOnlySpan<char> t2)
|
private static bool TokensCanMatch(ReadOnlySpan<char> t1, ReadOnlySpan<char> t2)
|
||||||
{
|
{
|
||||||
if (t1.Length == 1 && (t1[0] == Pwc || t1[0] == Fwc))
|
if (t1.Length == 1 && (t1[0] == Pwc || t1[0] == Fwc))
|
||||||
|
|||||||
Reference in New Issue
Block a user