// 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] } }