Skip to content

Commit

Permalink
fix(hub): fix cache key in SubscriberList (dunglas#689)
Browse files Browse the repository at this point in the history
* fix(hub): fix cache key in SubscriberList

* switch to ascii85

* use better characters
  • Loading branch information
dunglas authored Aug 12, 2022
1 parent d3ddc39 commit 4221a9e
Showing 1 changed file with 43 additions and 10 deletions.
53 changes: 43 additions & 10 deletions subscriber_list.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,65 @@
package mercure

import (
"encoding/ascii85"
"sort"
"strings"

"github.com/kevburnsjr/skipfilter"
)

type filter struct {
topics []string
private bool
}

type SubscriberList struct {
skipfilter *skipfilter.SkipFilter
}

func NewSubscriberList(size int) *SubscriberList {
return &SubscriberList{
skipfilter: skipfilter.New(func(s interface{}, fil interface{}) bool {
f := fil.(*filter)
skipfilter: skipfilter.New(func(s interface{}, filter interface{}) bool {
var private bool

encodedTopics := strings.Split(filter.(string), "~")
topics := make([]string, len(encodedTopics))
for i, encodedTopic := range encodedTopics {
p := strings.SplitN(encodedTopic, "}", 2)
if len(p) < 2 {
return false
}

if p[0] == "|" {
private = true
}

return s.(*Subscriber).MatchTopics(f.topics, f.private)
decodedTopic := make([]byte, len(p[1]))
ndst, _, err := ascii85.Decode(decodedTopic, []byte(p[1]), true)
if err != nil {
return false
}

topics[i] = string(decodedTopic[:ndst])
}

return s.(*Subscriber).MatchTopics(topics, private)
}, size),
}
}

func (sc *SubscriberList) MatchAny(u *Update) (res []*Subscriber) {
f := &filter{u.Topics, u.Private}
encodedTopics := make([]string, len(u.Topics))
for i, t := range u.Topics {
encodedTopic := make([]byte, ascii85.MaxEncodedLen(len(t)))
nb := ascii85.Encode(encodedTopic, []byte(t))
encodedTopic = encodedTopic[:nb]

if u.Private {
encodedTopics[i] = "|}" + string(encodedTopic)
} else {
encodedTopics[i] = "}" + string(encodedTopic)
}
}

sort.Strings(encodedTopics)

for _, m := range sc.skipfilter.MatchAny(f) {
for _, m := range sc.skipfilter.MatchAny(strings.Join(encodedTopics, "~")) {
res = append(res, m.(*Subscriber))
}

Expand Down

0 comments on commit 4221a9e

Please sign in to comment.