Skip to content

Commit

Permalink
[FIXED] Stree match bug, filestore minor improvements. (#5080)
Browse files Browse the repository at this point in the history
When encountering partial frags or parts we were not properly offsetting
by si. This would cause certain stree setups to fail to match properly
against wildcarded subjects that had to deal with partial frags and
partial parts.

Also lowered the prefix from 60 to 24.

Improved NumPending in filestore by check if fssLoaded vs whole cache.
  • Loading branch information
derekcollison committed Feb 14, 2024
2 parents 056ad18 + 6af5517 commit bd7ef64
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 10 deletions.
7 changes: 5 additions & 2 deletions server/filestore.go
Original file line number Diff line number Diff line change
Expand Up @@ -2824,7 +2824,7 @@ func (fs *fileStore) NumPending(sseq uint64, filter string, lastPerSubject bool)
} else {
// We need to adjust for all matches in this block.
// Make sure we have fss loaded. This loads whole block now.
if mb.cacheNotLoaded() {
if mb.fssNotLoaded() {
mb.loadMsgsWithLock()
shouldExpire = true
}
Expand Down Expand Up @@ -2877,7 +2877,10 @@ func (fs *fileStore) SubjectsTotals(filter string) map[string]uint64 {
if fs.psim.Size() == 0 {
return nil
}

// Match all if no filter given.
if filter == _EMPTY_ {
filter = fwcs
}
fst := make(map[string]uint64)
fs.psim.Match(stringToBytes(filter), func(subj []byte, psi *psi) {
fst[string(subj)] = psi.total
Expand Down
3 changes: 1 addition & 2 deletions server/stree/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ type node interface {

// Maximum prefix len
// We expect the most savings to come from long shared prefixes.
// This also makes the meta base layer exactly 64 bytes, a normal L1 cache line.
const maxPrefixLen = 60
const maxPrefixLen = 24

// 64 bytes total - an L1 cache line.
type meta struct {
Expand Down
7 changes: 3 additions & 4 deletions server/stree/parts.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,9 @@ func matchParts(parts [][]byte, frag []byte) ([][]byte, bool) {
}
end := min(si+lp, len(frag))
// If part is bigger then the fragment, adjust to a portion on the part.
partialPart := lp > end
if partialPart {
if partialPart := lp > end; partialPart {
// Frag is smaller then part itself.
part = part[:end]
part = part[:end-si]
}
if !bytes.Equal(part, frag[si:end]) {
return parts, false
Expand All @@ -117,7 +116,7 @@ func matchParts(parts [][]byte, frag []byte) ([][]byte, bool) {
if end < lp {
if end >= lf {
parts = append([][]byte{}, parts...) // Create a copy before modifying.
parts[i] = parts[i][lf:]
parts[i] = parts[i][lf-si:]
} else {
i++
}
Expand Down
2 changes: 1 addition & 1 deletion server/stree/stree.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func (t *SubjectTree[T]) match(n node, parts [][]byte, pre []byte, cb func(subje
}
// We have matched here. If we are a leaf and have exhausted all parts or he have a FWC fire callback.
if n.isLeaf() {
if len(nparts) == 0 || hasFWC {
if len(nparts) == 0 || (hasFWC && len(nparts) == 1) {
ln := n.(*leaf[T])
cb(append(pre, ln.suffix...), &ln.value)
}
Expand Down
14 changes: 13 additions & 1 deletion server/stree/stree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,18 @@ func TestSubjectTreeInsertSamePivotBug(t *testing.T) {
}
}

func TestSubjectTreeMatchTsepSecondThenPartialPartBug(t *testing.T) {
st := NewSubjectTree[int]()
st.Insert(b("foo.xxxxx.foo1234.zz"), 22)
st.Insert(b("foo.yyy.foo123.zz"), 22)
st.Insert(b("foo.yyybar789.zz"), 22)
st.Insert(b("foo.yyy.foo12345.zz"), 22)
st.Insert(b("foo.yyy.foo12345.yy"), 22)
st.Insert(b("foo.yyy.foo123456789.zz"), 22)
match(t, st, "foo.*.foo123456789.*", 1)
match(t, st, "foo.*.*.zzz.foo.>", 0)
}

func TestSubjectTreeRandomTrackEntries(t *testing.T) {
st := NewSubjectTree[int]()
smap := make(map[string]struct{}, 1000)
Expand Down Expand Up @@ -566,7 +578,7 @@ func TestSubjectTreeRandomTrackEntries(t *testing.T) {

func TestSubjectTreeMetaSize(t *testing.T) {
var base meta
require_Equal(t, unsafe.Sizeof(base), 64)
require_Equal(t, unsafe.Sizeof(base), 28)
}

func b(s string) []byte {
Expand Down

0 comments on commit bd7ef64

Please sign in to comment.