package pokecache import ( "sync" "time" ) type cacheEntry struct { val []byte createdAt time.Time } type Cache struct { entries map[string]cacheEntry lock sync.Mutex done chan struct{} once sync.Once } func NewCache(interval time.Duration) *Cache { c := Cache{ entries: map[string]cacheEntry{}, done: make(chan struct{}), } go c.runReapLoop(interval) return &c } func (c *Cache) runReapLoop(interval time.Duration) { ticker := time.NewTicker(interval) defer ticker.Stop() for { select { case <-ticker.C: c.lock.Lock() for k, v := range c.entries { if time.Since(v.createdAt) > interval { delete(c.entries, k) } } c.lock.Unlock() case <-c.done: return } } } func (c *Cache) Add(key string, value []byte) { c.lock.Lock() defer c.lock.Unlock() c.entries[key] = cacheEntry{ val: value, createdAt: time.Now(), } } func (c *Cache) Get(key string) ([]byte, bool) { c.lock.Lock() defer c.lock.Unlock() v, ok := c.entries[key] return v.val, ok } func (c *Cache) Stop() { c.once.Do(func() { close(c.done) }) }