feat: first init
This commit is contained in:
70
internal/cache/cache.go
vendored
Normal file
70
internal/cache/cache.go
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user