feat(batch13): port filestore skip-first-block query helpers
This commit is contained in:
@@ -2032,6 +2032,106 @@ public sealed class JetStreamFileStore : IStreamStore, IDisposable
|
||||
_lmb = _blks.Count > 0 ? _blks[^1] : null;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Read/query helper methods (Batch 13)
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// Lock should be held by caller.
|
||||
private (int Next, Exception? Error) CheckSkipFirstBlock(string filter, bool wc, int bi)
|
||||
{
|
||||
if (string.IsNullOrEmpty(filter) || filter == ">")
|
||||
return (bi + 1, null);
|
||||
|
||||
var start = uint.MaxValue;
|
||||
uint stop = 0;
|
||||
|
||||
if (_psim is { } psim)
|
||||
{
|
||||
if (wc)
|
||||
{
|
||||
psim.Match(Encoding.UTF8.GetBytes(filter), (_, psi) =>
|
||||
{
|
||||
if (psi.Fblk < start)
|
||||
start = psi.Fblk;
|
||||
if (psi.Lblk > stop)
|
||||
stop = psi.Lblk;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var (psi, ok) = psim.Find(Encoding.UTF8.GetBytes(filter));
|
||||
if (ok && psi != null)
|
||||
{
|
||||
start = psi.Fblk;
|
||||
stop = psi.Lblk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (start == uint.MaxValue)
|
||||
return (-1, StoreErrors.ErrStoreEOF);
|
||||
|
||||
return SelectSkipFirstBlock(bi, start, stop);
|
||||
}
|
||||
|
||||
// Lock should be held by caller.
|
||||
private (int Next, Exception? Error) CheckSkipFirstBlockMulti(SimpleSublist? sl, int bi)
|
||||
{
|
||||
if (_psim == null || sl == null)
|
||||
return (-1, StoreErrors.ErrStoreEOF);
|
||||
|
||||
var start = uint.MaxValue;
|
||||
uint stop = 0;
|
||||
|
||||
_psim.IterFast((subj, psi) =>
|
||||
{
|
||||
var matched = false;
|
||||
sl.Match(Encoding.UTF8.GetString(subj), _ => matched = true);
|
||||
if (matched)
|
||||
{
|
||||
if (psi.Fblk < start)
|
||||
start = psi.Fblk;
|
||||
if (psi.Lblk > stop)
|
||||
stop = psi.Lblk;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (start == uint.MaxValue)
|
||||
return (-1, StoreErrors.ErrStoreEOF);
|
||||
|
||||
return SelectSkipFirstBlock(bi, start, stop);
|
||||
}
|
||||
|
||||
// Lock should be held by caller.
|
||||
private (int Next, Exception? Error) SelectSkipFirstBlock(int bi, uint start, uint stop)
|
||||
{
|
||||
if (bi < 0 || bi >= _blks.Count)
|
||||
return (-1, StoreErrors.ErrStoreEOF);
|
||||
|
||||
var mbi = _blks[bi].Index;
|
||||
if (stop <= mbi)
|
||||
return (-1, StoreErrors.ErrStoreEOF);
|
||||
|
||||
if (start > mbi && _bim.TryGetValue(start, out var mb) && mb != null)
|
||||
{
|
||||
var ni = -1;
|
||||
for (var i = 0; i < _blks.Count; i++)
|
||||
{
|
||||
if (mb.Last.Seq <= _blks[i].Last.Seq)
|
||||
{
|
||||
ni = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (ni, null);
|
||||
}
|
||||
|
||||
return (bi + 1, null);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// IStreamStore — type / state
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user