feat(batch13): port filestore all-last-seqs and filter-is-all helpers

This commit is contained in:
Joseph Doherty
2026-02-28 14:49:00 -05:00
parent 3d2638dfaa
commit cda4c0c5b6
3 changed files with 243 additions and 2 deletions

View File

@@ -2300,6 +2300,92 @@ public sealed class JetStreamFileStore : IStreamStore, IDisposable
});
}
// Lock should be held by caller.
private (ulong[] Seqs, Exception? Error) AllLastSeqsLocked()
{
if (_state.Msgs == 0 || NoTrackSubjects() || _psim == null)
return (Array.Empty<ulong>(), null);
var numSubjects = _psim.Size();
if (numSubjects == 0)
return (Array.Empty<ulong>(), null);
var seqs = new List<ulong>(numSubjects);
var seen = new HashSet<string>(numSubjects, StringComparer.Ordinal);
for (var i = _blks.Count - 1; i >= 0; i--)
{
if (seen.Count == numSubjects)
break;
var mb = _blks[i];
if (mb.Fss == null)
continue;
mb.Fss.IterFast((subjectBytes, ss) =>
{
var subject = Encoding.UTF8.GetString(subjectBytes);
if (!seen.Add(subject))
return true;
if (ss.LastNeedsUpdate)
RecalculateLastForSubject(subject, ss);
seqs.Add(ss.Last);
return true;
});
}
seqs.Sort();
return (seqs.ToArray(), null);
}
// Lock should be held by caller.
private bool FilterIsAll(string[] filters)
{
ArgumentNullException.ThrowIfNull(filters);
var streamSubjects = _cfg.Config.Subjects ?? [];
if (filters.Length != streamSubjects.Length)
return false;
var sortedFilters = filters.ToArray();
var sortedSubjects = streamSubjects.ToArray();
Array.Sort(sortedFilters, StringComparer.Ordinal);
Array.Sort(sortedSubjects, StringComparer.Ordinal);
for (var i = 0; i < sortedFilters.Length; i++)
{
if (!SubscriptionIndex.SubjectIsSubsetMatch(sortedSubjects[i], sortedFilters[i]))
return false;
}
return true;
}
// Lock should be held by caller.
private void RecalculateLastForSubject(string subject, SimpleState ss)
{
var subjectBytes = Encoding.UTF8.GetBytes(subject);
for (var i = _blks.Count - 1; i >= 0; i--)
{
var fss = _blks[i].Fss;
if (fss == null)
continue;
var (candidate, ok) = fss.Find(subjectBytes);
if (!ok || candidate == null || candidate.Last == 0)
continue;
ss.Last = candidate.Last;
ss.LastNeedsUpdate = false;
return;
}
ss.Last = 0;
ss.LastNeedsUpdate = false;
}
// -----------------------------------------------------------------------
// IStreamStore — type / state
// -----------------------------------------------------------------------