Skip to content

Commit 56548be

Browse files
committed
LoadNextMsgMulti and LoadPrevMsgMulti use fast path for single filter
Signed-off-by: Neil Twigg <neil@nats.io>
1 parent b1776c6 commit 56548be

4 files changed

Lines changed: 33 additions & 4 deletions

File tree

server/filestore.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8369,6 +8369,9 @@ func (fs *fileStore) LoadNextMsgMulti(sl *gsl.SimpleSublist, start uint64, smp *
83698369
if sl == nil || sl.MatchesFullWildcard() {
83708370
return fs.LoadNextMsg(_EMPTY_, false, start, smp)
83718371
}
8372+
if filter, ok := sl.MatchesSingleFilter(); ok {
8373+
return fs.LoadNextMsg(filter, subjectHasWildcard(filter), start, smp)
8374+
}
83728375
fs.mu.RLock()
83738376
defer fs.mu.RUnlock()
83748377

@@ -8702,6 +8705,9 @@ func (fs *fileStore) LoadPrevMsgMulti(sl *gsl.SimpleSublist, start uint64, smp *
87028705
if sl == nil || sl.MatchesFullWildcard() {
87038706
return fs.LoadPrevMsg(_EMPTY_, false, start, smp)
87048707
}
8708+
if filter, ok := sl.MatchesSingleFilter(); ok {
8709+
return fs.LoadPrevMsg(filter, subjectHasWildcard(filter), start, smp)
8710+
}
87058711
fs.mu.RLock()
87068712
defer fs.mu.RUnlock()
87078713

server/gsl/gsl.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ func singleFilter[T comparable](l *level[T], filter string) (string, bool) {
194194
if l == nil {
195195
return filter, filter != _EMPTY_
196196
}
197-
197+
if len(l.nodes) > 1 {
198+
return _EMPTY_, false
199+
}
198200
var next *node[T]
199201
branches := 0
200202
if l.pwc != nil {
@@ -208,7 +210,6 @@ func singleFilter[T comparable](l *level[T], filter string) (string, bool) {
208210
for _, n := range l.nodes {
209211
next = n
210212
branches++
211-
break
212213
}
213214
if branches != 1 {
214215
return _EMPTY_, false
@@ -221,7 +222,7 @@ func singleFilter[T comparable](l *level[T], filter string) (string, bool) {
221222
return filter, filter != _EMPTY_
222223
}
223224
if filter != _EMPTY_ {
224-
if _, ok := singleFilter(next.next, _EMPTY_); ok {
225+
if next.next.numNodes() > 0 {
225226
return _EMPTY_, false
226227
}
227228
return filter, true

server/gsl/gsl_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,32 @@ func TestGenericSublistSingleFilter(t *testing.T) {
275275
require_True(t, ok)
276276
require_Equal(t, filter, "stream.A.child")
277277

278+
require_NoError(t, s.Insert("stream.A.other", 22))
279+
filter, ok = s.MatchesSingleFilter()
280+
require_False(t, ok)
281+
require_Equal(t, filter, _EMPTY_)
282+
278283
require_NoError(t, s.Insert("stream.*", 33))
279284
filter, ok = s.MatchesSingleFilter()
280285
require_False(t, ok)
281286
require_Equal(t, filter, _EMPTY_)
287+
288+
// Test that an ancestor with descendants correctly returns false.
289+
s2 := NewSublist[int]()
290+
require_NoError(t, s2.Insert("foo", 1))
291+
require_NoError(t, s2.Insert("foo.bar", 2))
292+
require_NoError(t, s2.Insert("foo.baz", 3))
293+
filter, ok = s2.MatchesSingleFilter()
294+
require_False(t, ok)
295+
require_Equal(t, filter, _EMPTY_)
296+
297+
// Test that an ancestor with only descendants correctly returns false.
298+
s3 := NewSublist[int]()
299+
require_NoError(t, s3.Insert("foo.bar", 2))
300+
require_NoError(t, s3.Insert("foo.baz", 3))
301+
filter, ok = s3.MatchesSingleFilter()
302+
require_False(t, ok)
303+
require_Equal(t, filter, _EMPTY_)
282304
}
283305

284306
// TestGenericSublistHasInterestStartingInRace tests that HasInterestStartingIn

server/memstore.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1975,7 +1975,7 @@ func (ms *memStore) LoadPrevMsgMulti(sl *gsl.SimpleSublist, start uint64, smp *S
19751975
return smp, nseq, nil
19761976
}
19771977
}
1978-
return nil, ms.state.LastSeq, ErrStoreEOF
1978+
return nil, ms.state.FirstSeq, ErrStoreEOF
19791979
}
19801980

19811981
// RemoveMsg will remove the message from this store.

0 commit comments

Comments
 (0)