speed up filters with another layer of cache map
Ted Unangst tedu@tedunangst.com
Mon, 23 Dec 2019 05:49:51 -0500
M
hfcs.go
→
hfcs.go
@@ -67,11 +67,12 @@ }
type afiltermap map[filtType][]*Filter +var filtInvalidator cache.Invalidator var filtcache *cache.Cache func init() { // resolve init loop - filtcache = cache.New(cache.Options{Filler: filtcachefiller}) + filtcache = cache.New(cache.Options{Filler: filtcachefiller, Invalidator: &filtInvalidator}) } func filtcachefiller(userid int64) (afiltermap, bool) {@@ -157,7 +158,7 @@ }
func filtcacheclear(userid int64, dur time.Duration) { time.Sleep(dur + time.Second) - filtcache.Clear(userid) + filtInvalidator.Clear(userid) } func getfilters(userid int64, scope filtType) []*Filter {@@ -169,19 +170,44 @@ }
return nil } -func rejectorigin(userid int64, origin string, isannounce bool) bool { - if o := originate(origin); o != "" { - origin = o - } +type arejectmap map[string][]*Filter + +var rejectAnyKey = "..." + +var rejectcache = cache.New(cache.Options{Filler: func(userid int64) (arejectmap, bool) { + m := make(arejectmap) filts := getfilters(userid, filtReject) for _, f := range filts { if f.Text != "" { + key := rejectAnyKey + m[key] = append(m[key], f) continue } - if f.IsAnnounce { - if !isannounce { - continue - } + if f.IsAnnounce && f.AnnounceOf != "" { + key := f.AnnounceOf + m[key] = append(m[key], f) + } + if f.Actor != "" { + key := f.Actor + m[key] = append(m[key], f) + } + } + return m, true +}, Invalidator: &filtInvalidator}) + +func rejectfilters(userid int64, name string) []*Filter { + var m arejectmap + rejectcache.Get(userid, &m) + return m[name] +} + +func rejectorigin(userid int64, origin string, isannounce bool) bool { + if o := originate(origin); o != "" { + origin = o + } + filts := rejectfilters(userid, origin) + for _, f := range filts { + if isannounce && f.IsAnnounce { if f.AnnounceOf == origin { log.Printf("rejecting announce: %s", origin) return true@@ -196,13 +222,26 @@ return false
} func rejectactor(userid int64, actor string) bool { + filts := rejectfilters(userid, actor) + for _, f := range filts { + if f.IsAnnounce { + continue + } + if f.Actor == actor { + log.Printf("rejecting actor: %s", actor) + return true + } + } origin := originate(actor) - filts := getfilters(userid, filtReject) + if origin == "" { + return false + } + filts = rejectfilters(userid, origin) for _, f := range filts { - if f.IsAnnounce || f.Text != "" { + if f.IsAnnounce { continue } - if f.Actor == actor || (origin != "" && f.Actor == origin) { + if f.Actor == origin { log.Printf("rejecting actor: %s", actor) return true }@@ -287,10 +326,17 @@ return ""
} func rejectxonk(xonk *Honk) bool { - filts := getfilters(xonk.UserID, filtReject) + var m arejectmap + rejectcache.Get(xonk.UserID, &m) + filts := m[rejectAnyKey] + filts = append(filts, m[xonk.Honker]...) + filts = append(filts, m[xonk.Oonker]...) + for _, a := range xonk.Audience { + filts = append(filts, m[a]...) + } for _, f := range filts { - if matchfilter(xonk, f) { - log.Printf("rejecting %s because %s", xonk.XID, f.Actor) + if cause := matchfilterX(xonk, f); cause != "" { + log.Printf("rejecting %s because %s", xonk.XID, cause) return true } }
M
web.go
→
web.go
@@ -1874,7 +1874,7 @@ _, err := stmtDeleteFilter.Exec(userinfo.UserID, hfcsid)
if err != nil { log.Printf("error deleting filter: %s", err) } - filtcache.Clear(userinfo.UserID) + filtInvalidator.Clear(userinfo.UserID) http.Redirect(w, r, "/hfcs", http.StatusSeeOther) return }@@ -1912,7 +1912,7 @@ if err != nil {
log.Printf("error saving filter: %s", err) } - filtcache.Clear(userinfo.UserID) + filtInvalidator.Clear(userinfo.UserID) http.Redirect(w, r, "/hfcs", http.StatusSeeOther) }