46 lines
1.1 KiB
Go
46 lines
1.1 KiB
Go
// Package cache is used for completion to not overflow the gateway with redundant search requests.
|
|
package cache
|
|
|
|
import (
|
|
"sync"
|
|
)
|
|
|
|
type Cache struct {
|
|
items sync.Map
|
|
}
|
|
|
|
func NewCache() *Cache {
|
|
return &Cache{}
|
|
}
|
|
|
|
func (c *Cache) Create(query string, value uint) {
|
|
c.items.Store(query, value)
|
|
}
|
|
|
|
func (c *Cache) Get(query string) (uint, bool) {
|
|
i, ok := c.items.Load(query)
|
|
if !ok {
|
|
return 0, false
|
|
}
|
|
return i.(uint), true
|
|
}
|
|
|
|
// Invalidate is only needed when a member leaves and the search query reaches
|
|
// the search limit.
|
|
// "aa", "ab", "ac", ..., "ay" // where length is longer than the limit
|
|
// if "ay" leaves, then "az" would not be loaded becaue it would not be
|
|
// returned by the search results because of the search limit.
|
|
func (c *Cache) Invalidate(name string, limit uint) {
|
|
for name != "" {
|
|
if v, ok := c.items.Load(name); ok && v.(uint) >= limit {
|
|
// This query, and every shorter prefix of it, may now be missing
|
|
// results, so drop the whole chain to force a fresh search.
|
|
for name != "" {
|
|
c.items.Delete(name)
|
|
name = name[:len(name)-1]
|
|
}
|
|
return
|
|
}
|
|
name = name[:len(name)-1]
|
|
}
|
|
}
|