Resources allocation improvement.

This commit is contained in:
2023-10-13 15:26:24 +01:00
parent dbd005bdcf
commit 7293583a99
+23 -18
View File
@@ -11,31 +11,29 @@ type CacheEntry struct {
} }
type Cache struct { type Cache struct {
sync.Mutex sync.RWMutex
entries map[string]CacheEntry entries map[string]CacheEntry
globalTTL time.Duration globalTTL time.Duration
ticker *time.Ticker
} }
func New(globalTTL time.Duration) *Cache { func New(globalTTL time.Duration) *Cache {
cache := &Cache{ cache := &Cache{
entries: make(map[string]CacheEntry), entries: make(map[string]CacheEntry),
globalTTL: globalTTL, globalTTL: globalTTL,
ticker: time.NewTicker(globalTTL / 2),
} }
// Start the cache. // Start the cache cleanup.
cache.Start() go cache.cleanupRoutine(globalTTL)
return cache return cache
} }
func (c *Cache) Start() { func (c *Cache) cleanupRoutine(globalTTL time.Duration) {
go func() { ticker := time.NewTicker(globalTTL / 2)
for { defer ticker.Stop()
<-c.ticker.C
c.CleanExpiredEntries() for range ticker.C {
} c.CleanExpiredEntries()
}() }
} }
func (c *Cache) Set(key string, value []byte, ttl time.Duration) { func (c *Cache) Set(key string, value []byte, ttl time.Duration) {
@@ -55,8 +53,8 @@ func (c *Cache) Set(key string, value []byte, ttl time.Duration) {
} }
func (c *Cache) Get(key string) ([]byte, bool) { func (c *Cache) Get(key string) ([]byte, bool) {
c.Lock() c.RLock()
defer c.Unlock() defer c.RUnlock()
entry, ok := c.entries[key] entry, ok := c.entries[key]
if !ok || entry.ExpiresAt.Before(time.Now()) { if !ok || entry.ExpiresAt.Before(time.Now()) {
@@ -75,13 +73,20 @@ func (c *Cache) Delete(key string) {
func (c *Cache) CleanExpiredEntries() { func (c *Cache) CleanExpiredEntries() {
now := time.Now() now := time.Now()
toDelete := make([]string, 0)
c.Lock() c.RLock()
defer c.Unlock()
for key, entry := range c.entries { for key, entry := range c.entries {
if entry.ExpiresAt.Before(now) { if entry.ExpiresAt.Before(now) {
delete(c.entries, key) toDelete = append(toDelete, key)
} }
} }
c.RUnlock()
// Separate the deletion to its own critical section to reduce lock contention.
c.Lock()
for _, key := range toDelete {
delete(c.entries, key)
}
c.Unlock()
} }