diff --git a/activity.go b/activity.go index 225ebb2..9081c9a 100644 --- a/activity.go +++ b/activity.go @@ -31,6 +31,7 @@ import ( "strings" "time" + "humungus.tedunangst.com/r/webs/cache" "humungus.tedunangst.com/r/webs/htfilter" "humungus.tedunangst.com/r/webs/httpsig" "humungus.tedunangst.com/r/webs/image" @@ -256,7 +257,7 @@ type Box struct { Shared string } -var boxofboxes = cacheNew(cacheOptions{Filler: func(ident string) (*Box, bool) { +var boxofboxes = cache.New(cache.Options{Filler: func(ident string) (*Box, bool) { var info string row := stmtGetXonker.QueryRow(ident, "boxes") err := row.Scan(&info) @@ -1118,7 +1119,7 @@ func jonkjonk(user *WhatAbout, h *Honk) (junk.Junk, junk.Junk) { return j, jo } -var oldjonks = cacheNew(cacheOptions{Filler: func(xid string) ([]byte, bool) { +var oldjonks = cache.New(cache.Options{Filler: func(xid string) ([]byte, bool) { row := stmtAnyXonk.QueryRow(xid) honk := scanhonk(row) if honk == nil || !honk.Public { @@ -1185,7 +1186,7 @@ func honkworldwide(user *WhatAbout, honk *Honk) { } } -var oldjonkers = cacheNew(cacheOptions{Filler: func(name string) ([]byte, bool) { +var oldjonkers = cache.New(cache.Options{Filler: func(name string) ([]byte, bool) { user, err := butwhatabout(name) if err != nil { return nil, false @@ -1226,7 +1227,7 @@ func asjonker(name string) ([]byte, bool) { return j, ok } -var handfull = cacheNew(cacheOptions{Filler: func(name string) (string, bool) { +var handfull = cache.New(cache.Options{Filler: func(name string) (string, bool) { m := strings.Split(name, "@") if len(m) != 2 { log.Printf("bad fish name: %s", name) diff --git a/cache.go b/cache.go deleted file mode 100644 index c2250a4..0000000 --- a/cache.go +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2019 Ted Unangst -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -package main - -import ( - "reflect" - "sync" - "time" -) - -type cacheFiller func(key interface{}) (interface{}, bool) - -type cacheOptions struct { - Filler interface{} - Duration time.Duration -} - -type Cache struct { - cache map[interface{}]interface{} - filler cacheFiller - lock sync.Mutex - stale time.Time - duration time.Duration -} - -func cacheNew(options cacheOptions) *Cache { - c := new(Cache) - c.cache = make(map[interface{}]interface{}) - fillfn := options.Filler - ftype := reflect.TypeOf(fillfn) - if ftype.Kind() != reflect.Func { - panic("cache filler is not function") - } - if ftype.NumIn() != 1 || ftype.NumOut() != 2 { - panic("cache filler has wrong argument count") - } - c.filler = func(key interface{}) (interface{}, bool) { - vfn := reflect.ValueOf(fillfn) - args := []reflect.Value{reflect.ValueOf(key)} - rv := vfn.Call(args) - return rv[0].Interface(), rv[1].Bool() - } - if options.Duration != 0 { - c.duration = options.Duration - c.stale = time.Now().Add(c.duration) - } - return c -} - -func (cache *Cache) Get(key interface{}, value interface{}) bool { - cache.lock.Lock() - defer cache.lock.Unlock() - if !cache.stale.IsZero() && cache.stale.Before(time.Now()) { - cache.stale = time.Now().Add(cache.duration) - cache.cache = make(map[interface{}]interface{}) - } - v, ok := cache.cache[key] - if !ok { - v, ok = cache.filler(key) - if ok { - cache.cache[key] = v - } - } - if ok { - ptr := reflect.ValueOf(v) - reflect.ValueOf(value).Elem().Set(ptr) - } - return ok -} - -func (cache *Cache) Clear(key interface{}) { - cache.lock.Lock() - defer cache.lock.Unlock() - delete(cache.cache, key) -} - -func (cache *Cache) Flush() { - cache.lock.Lock() - defer cache.lock.Unlock() - cache.cache = make(map[interface{}]interface{}) -} diff --git a/database.go b/database.go index 708df2a..43f999e 100644 --- a/database.go +++ b/database.go @@ -26,10 +26,11 @@ import ( "strings" "time" + "humungus.tedunangst.com/r/webs/cache" "humungus.tedunangst.com/r/webs/login" ) -var someusers = cacheNew(cacheOptions{Filler: func(name string) (*WhatAbout, bool) { +var someusers = cache.New(cache.Options{Filler: func(name string) (*WhatAbout, bool) { row := stmtWhatAbout.QueryRow(name) user := new(WhatAbout) var options string diff --git a/fun.go b/fun.go index ed27385..953ad74 100644 --- a/fun.go +++ b/fun.go @@ -28,6 +28,7 @@ import ( "sync" "golang.org/x/net/html" + "humungus.tedunangst.com/r/webs/cache" "humungus.tedunangst.com/r/webs/htfilter" "humungus.tedunangst.com/r/webs/httpsig" ) @@ -365,7 +366,7 @@ func quickrename(s string, userid int64) string { return s } -var shortnames = cacheNew(cacheOptions{Filler: func(userid int64) (map[string]string, bool) { +var shortnames = cache.New(cache.Options{Filler: func(userid int64) (map[string]string, bool) { honkers := gethonkers(userid) m := make(map[string]string) for _, h := range honkers { diff --git a/hfcs.go b/hfcs.go index 06f831e..50b4301 100644 --- a/hfcs.go +++ b/hfcs.go @@ -21,6 +21,8 @@ import ( "regexp" "sort" "time" + + "humungus.tedunangst.com/r/webs/cache" ) type Filter struct { @@ -63,7 +65,7 @@ func (ft filtType) String() string { type afiltermap map[filtType][]*Filter -var filtcache = cacheNew(cacheOptions{Filler: func(userid int64) (afiltermap, bool) { +var filtcache = cache.New(cache.Options{Filler: func(userid int64) (afiltermap, bool) { rows, err := stmtGetFilters.Query(userid) if err != nil { log.Printf("error querying filters: %s", err) diff --git a/web.go b/web.go index a18689e..ff9a320 100644 --- a/web.go +++ b/web.go @@ -33,6 +33,7 @@ import ( "time" "github.com/gorilla/mux" + "humungus.tedunangst.com/r/webs/cache" "humungus.tedunangst.com/r/webs/css" "humungus.tedunangst.com/r/webs/htfilter" "humungus.tedunangst.com/r/webs/httpsig" @@ -471,7 +472,7 @@ func xzone(w http.ResponseWriter, r *http.Request) { } } -var oldoutbox = cacheNew(cacheOptions{Filler: func(name string) ([]byte, bool) { +var oldoutbox = cache.New(cache.Options{Filler: func(name string) ([]byte, bool) { user, err := butwhatabout(name) if err != nil { return nil, false @@ -1235,7 +1236,7 @@ func showhonkers(w http.ResponseWriter, r *http.Request) { } } -var combocache = cacheNew(cacheOptions{Filler: func(userid int64) ([]string, bool) { +var combocache = cache.New(cache.Options{Filler: func(userid int64) ([]string, bool) { honkers := gethonkers(userid) var combos []string for _, h := range honkers {