perf: reduce SubList token string churn

This commit is contained in:
Joseph Doherty
2026-03-13 09:53:37 -04:00
parent 348bec36b2
commit 5876ad7dfa
2 changed files with 31 additions and 4 deletions

View File

@@ -362,9 +362,9 @@ public sealed class SubList : IDisposable
}
else
{
var key = token.ToString();
if (!level.Nodes.TryGetValue(key, out node))
if (!TryGetLiteralNode(level, token, out _, out node))
{
var key = token.ToString();
node = new TrieNode();
level.Nodes[key] = node;
}
@@ -474,13 +474,20 @@ public sealed class SubList : IDisposable
}
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)
return false; // not found
var tokenStr = token.ToString();
var tokenStr = isPwc ? "*" : ">";
pathList.Add((level, node, tokenStr, isPwc, isFwc));
if (node.Next == null)
return false; // corrupted trie state
@@ -652,6 +659,23 @@ public sealed class SubList : IDisposable
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)
{
var subs = new List<Subscription>();

View File

@@ -249,6 +249,9 @@ public static class SubjectMatch
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)
{
if (t1.Length == 1 && (t1[0] == Pwc || t1[0] == Fwc))