diff --git a/server/sublist.go b/server/sublist.go index ae5b48e1de..4df3927e49 100644 --- a/server/sublist.go +++ b/server/sublist.go @@ -102,29 +102,38 @@ func (s *Sublist) Insert(sub *subscription) error { var n *node for _, t := range tokens { - if len(t) == 0 || sfwc { + lt := len(t) + if lt == 0 || sfwc { s.Unlock() return ErrInvalidSubject } - switch t[0] { - case pwc: - n = l.pwc - case fwc: - n = l.fwc - sfwc = true - default: + if lt > 1 { n = l.nodes[t] - } - if n == nil { - n = newNode() + } else { switch t[0] { case pwc: - l.pwc = n + n = l.pwc case fwc: - l.fwc = n + n = l.fwc + sfwc = true default: + n = l.nodes[t] + } + } + if n == nil { + n = newNode() + if lt > 1 { l.nodes[t] = n + } else { + switch t[0] { + case pwc: + l.pwc = n + case fwc: + l.fwc = n + default: + l.nodes[t] = n + } } } if n.next == nil { @@ -334,20 +343,25 @@ func (s *Sublist) Remove(sub *subscription) error { levels := lnts[:0] for _, t := range tokens { - if len(t) == 0 || sfwc { + lt := len(t) + if lt == 0 || sfwc { return ErrInvalidSubject } if l == nil { return ErrNotFound } - switch t[0] { - case pwc: - n = l.pwc - case fwc: - n = l.fwc - sfwc = true - default: + if lt > 1 { n = l.nodes[t] + } else { + switch t[0] { + case pwc: + n = l.pwc + case fwc: + n = l.fwc + sfwc = true + default: + n = l.nodes[t] + } } if n != nil { levels = append(levels, lnt{l, n, t}) diff --git a/server/sublist_test.go b/server/sublist_test.go index a5229133f5..a7df7b1582 100644 --- a/server/sublist_test.go +++ b/server/sublist_test.go @@ -475,6 +475,40 @@ func TestSublistTwoTokenPubMatchSingleTokenSub(t *testing.T) { verifyLen(r.psubs, 0, t) } +func TestSublistInsertWithWildcardsAsLiterals(t *testing.T) { + s := NewSublist() + subjects := []string{"foo.*-", "foo.>-"} + for _, subject := range subjects { + sub := newSub(subject) + s.Insert(sub) + // Should find no match + r := s.Match("foo.bar") + verifyLen(r.psubs, 0, t) + // Should find a match + r = s.Match(subject) + verifyLen(r.psubs, 1, t) + } +} + +func TestSublistRemoveWithWildcardsAsLiterals(t *testing.T) { + s := NewSublist() + subjects := []string{"foo.*-", "foo.>-"} + for _, subject := range subjects { + sub := newSub(subject) + s.Insert(sub) + // Should find no match + rsub := newSub("foo.bar") + s.Remove(rsub) + if c := s.Count(); c != 1 { + t.Fatalf("Expected sublist to still contain sub, got %v", c) + } + s.Remove(sub) + if c := s.Count(); c != 0 { + t.Fatalf("Expected sublist to be empty, got %v", c) + } + } +} + // -- Benchmarks Setup -- var subs []*subscription