// NewCachedAnnouncementStore returns a cache wrapper around the existing store func NewCachedAnnouncementStore(store Store, options CacheOptions) Store { serviceCache := gcache.New(options.ServiceCacheSize).Expiration(options.ServiceCacheExpiration).LRU(). LoaderFunc(func(k interface{}) (interface{}, error) { key := strings.Split(k.(string), ":") return store.Get(key[0], key[1]) }).Build() listCache := gcache.New(options.ListCacheSize).Expiration(options.ListCacheExpiration).LRU(). LoaderFunc(func(k interface{}) (interface{}, error) { key := k.(string) announcements, err := store.ListService(key) if err != nil { return nil, err } go func(announcements []*Announcement) { for _, announcement := range announcements { serviceCache.Set(serviceCacheKey(announcement.ServiceName, announcement.ID), announcement) } }(announcements) return announcements, nil }).Build() return &cachedAnnouncementStore{ backingStore: store, serviceCache: serviceCache, listCache: listCache, } }
func buildLoadingARCache(size int) gcache.Cache { return gcache.New(size). ARC(). LoaderFunc(loader). EvictedFunc(evictedFuncForARC). Build() }
func buildLoadingSimpleCache(size int, loader gcache.LoaderFunc) gcache.Cache { return gcache.New(size). LoaderFunc(loader). Simple(). EvictedFunc(evictedFuncForSimple). Build() }
// NewClient returns a new Client func NewClient(server string, announcement *Announcement, tokenFunc func() string) (Client, error) { conn, err := api.Dial(server) if err != nil { return nil, err } client := &DefaultClient{ lists: make(map[string][]*Announcement), listsUpdated: make(map[string]time.Time), self: announcement, tokenFunc: tokenFunc, conn: conn, client: NewDiscoveryClient(conn), } client.cache = gcache. New(CacheSize). Expiration(CacheExpiration). LRU(). LoaderFunc(func(k interface{}) (interface{}, error) { key, ok := k.(cacheKey) if !ok { return nil, fmt.Errorf("wrong type for cacheKey: %T", k) } return client.get(key.serviceName, key.id) }). Build() return client, nil }
func buildLRUCache(size int) gcache.Cache { return gcache.New(size). LRU(). EvictedFunc(evictedFuncForLRU). Expiration(time.Second). Build() }
func main() { defer mustbe.Catched(func(err error) { log.Fatalln("Fatal error:", err) }) var ( botToken string apiHost string dbFileName string ) flag.StringVar(&botToken, "token", "", "telegram bot token") flag.StringVar(&apiHost, "apihost", "freefeed.net", "backend API host") flag.StringVar(&dbFileName, "dbfile", "", "database file name") flag.Parse() if botToken == "" || dbFileName == "" { flag.Usage() return } db := mustbe.OKVal(bolt.Open(dbFileName, 0600, &bolt.Options{Timeout: 1 * time.Second})).(*bolt.DB) defer db.Close() mustbe.OK(db.Update(func(tx *bolt.Tx) error { mustbe.OKVal(tx.CreateBucketIfNotExists(StatesBucket)) return nil })) bot := mustbe.OKVal(tgbotapi.NewBotAPI(botToken)).(*tgbotapi.BotAPI) u := tgbotapi.NewUpdate(0) u.Timeout = 60 updates, err := bot.GetUpdatesChan(u) if err != nil { log.Fatalln("Can not get update chan:", err) return } log.Println("Starting bot", bot.Self.UserName) app := &App{ db: db, apiHost: apiHost, outbox: make(chan tgbotapi.Chattable, 0), rts: make(map[int]*Realtime), cache: gcache.New(1000).ARC().Build(), } app.LoadRT() for { select { case update := <-updates: go app.HandleMessage(&update.Message) case msg := <-app.outbox: bot.Send(msg) } } }
func buildLoadingLRUCache(size int, loader gcache.LoaderFunc) gcache.Cache { return gcache.New(size). LRU(). LoaderFunc(loader). EvictedFunc(evictedFuncForLRU). Expiration(time.Second). Build() }
// newReverseResolver starts a new reverse resolver that performs reverse // resolutions and caches the result. func newReverseResolver() *reverseResolver { r := reverseResolver{ addresses: make(chan string, rAddrBacklog), cache: gcache.New(rAddrCacheLen).LRU().Expiration(rAddrCacheExpiration).Build(), Throttle: time.Tick(time.Second / 10), Resolver: net.LookupAddr, } go r.loop() return &r }
func main() { gc := gcache.New(10). LFU(). Build() gc.Set("key", "ok") v, err := gc.Get("key") if err != nil { panic(err) } fmt.Println("value:", v) }
func main() { gc := gcache.New(10). LFU(). LoaderFunc(func(key interface{}) (interface{}, error) { return fmt.Sprintf("%v-value", key), nil }). Build() v, err := gc.Get("key") if err != nil { panic(err) } fmt.Println(v) }
func buildARCache(size int) gcache.Cache { return gcache.New(size). ARC(). EvictedFunc(evictedFuncForARC). Build() }
package render import ( "fmt" "math/rand" "github.com/bluele/gcache" "$GITHUB_URI/report" ) var renderCache = gcache.New(100).LRU().Build() type memoise struct { Renderer id string } // Memoise wraps the renderer in a loving embrace of caching func Memoise(r Renderer) Renderer { return &memoise{ Renderer: r, id: fmt.Sprintf("%x", rand.Int63()), } } // Render produces a set of Nodes given a Report. // Ideally, it just retrieves it from the cache, otherwise it calls through to // `r` and stores the result. func (m *memoise) Render(rpt report.Report, dct Decorator) report.Nodes { key := fmt.Sprintf("%s-%s", rpt.ID, m.id)
// Delimiters are used to separate parts of node IDs, to guarantee uniqueness // in particular contexts. const ( // ScopeDelim is a general-purpose delimiter used within node IDs to // separate different contextual scopes. Different topologies have // different key structures. ScopeDelim = ";" // EdgeDelim separates two node IDs when they need to exist in the same key. // Concretely, it separates node IDs in keys that represent edges. EdgeDelim = "|" ) var ( idCache = gcache.New(1024).LRU().Build() hashers = sync.Pool{ New: func() interface{} { return fnv.New64a() }, } ) func lookupID(part1, part2, part3 string, f func() string) string { h := hashers.Get().(hash.Hash64) h.Write([]byte(part1)) h.Write([]byte(part2)) h.Write([]byte(part3)) sum := h.Sum64() var result string if id, err := idCache.Get(sum); id != nil && err != nil {
func NewCache(s int) CacheMiddleware { c := new(inMemoryCacheMiddleware) c.cache = gcache.New(s).LRU().Build() return c }
func buildSimpleCache(size int) gcache.Cache { return gcache.New(size). Simple(). EvictedFunc(evictedFuncForSimple). Build() }
package main import ( "fmt" "strconv" "time" "github.com/bluele/gcache" ) const cacheSize = 500 // On every connect and accept, we lookup the local addr // As this is expensive, we cache the result var fdAddrCache = gcache.New(cacheSize).LRU().Expiration(15 * time.Second).Build() type fdCacheKey struct { pid int fd int } type fdCacheValue struct { addr uint32 port uint16 } func getCachedLocalAddr(pid, fd int) (uint32, uint16, error) { key := fdCacheKey{pid, fd} val, err := fdAddrCache.Get(key) if val != nil { return val.(fdCacheValue).addr, val.(fdCacheValue).port, nil }