package cache import ( "sync" "time" ) // Item represents an item in the cache type Item struct { Value any Expiration int64 } // Cache type Cache struct { mu sync.RWMutex items map[string]Item } // Create new cache func NewCache(cleanupInterval time.Duration) *Cache { cache := &Cache{ items: make(map[string]Item), } // Start janitor process go cache.janitor(cleanupInterval) return cache } // Set adds an item to the cache with a Time to Live (TTL) func (c *Cache) Set(key string, value any, ttl time.Duration) { expiration := time.Now().Add(ttl).UnixNano() // Lock mutex c.mu.Lock() defer c.mu.Unlock() c.items[key] = Item{ Value: value, Expiration: expiration, } } // Get retrieves an item, checking if it has expired func (c *Cache) Get(key string) (any, bool) { c.mu.RLock() defer c.mu.RUnlock() item, found := c.items[key] if !found || time.Now().UnixNano() > item.Expiration { return nil, false } return item.Value, true } func (c *Cache) janitor(interval time.Duration) { ticker := time.NewTicker(interval) for range ticker.C { c.mu.Lock() for k, v := range c.items { if time.Now().UnixNano() > v.Expiration { delete(c.items, k) } } c.mu.Unlock() } }