mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-01 01:41:13 -06:00
79 lines
1.4 KiB
Go
79 lines
1.4 KiB
Go
package cache
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Entry represents an entry on the cache. You can type assert on V.
|
|
type Entry struct {
|
|
V interface{}
|
|
expiration time.Time
|
|
}
|
|
|
|
// Cache is a barebones cache implementation.
|
|
type Cache struct {
|
|
entries map[string]*Entry
|
|
size int
|
|
m sync.Mutex
|
|
}
|
|
|
|
// NewCache returns a new instance of Cache.
|
|
func NewCache(o ...Option) Cache {
|
|
opts := newOptions(o...)
|
|
|
|
return Cache{
|
|
size: opts.size,
|
|
entries: map[string]*Entry{},
|
|
}
|
|
}
|
|
|
|
// Get gets a role-bundle by a given `roleID`.
|
|
func (c *Cache) Get(k string) *Entry {
|
|
c.m.Lock()
|
|
defer c.m.Unlock()
|
|
|
|
if _, ok := c.entries[k]; ok {
|
|
if c.expired(c.entries[k]) {
|
|
delete(c.entries, k)
|
|
return nil
|
|
}
|
|
return c.entries[k]
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Set sets a roleID / role-bundle.
|
|
func (c *Cache) Set(k string, val interface{}, expiration time.Time) {
|
|
c.m.Lock()
|
|
defer c.m.Unlock()
|
|
|
|
if !c.fits() {
|
|
c.evict()
|
|
}
|
|
|
|
c.entries[k] = &Entry{
|
|
val,
|
|
expiration,
|
|
}
|
|
}
|
|
|
|
// evict frees memory from the cache by removing entries that exceeded the cache TTL.
|
|
func (c *Cache) evict() {
|
|
for i := range c.entries {
|
|
if c.expired(c.entries[i]) {
|
|
delete(c.entries, i)
|
|
}
|
|
}
|
|
}
|
|
|
|
// expired checks if an entry is expired
|
|
func (c *Cache) expired(e *Entry) bool {
|
|
return e.expiration.Before(time.Now())
|
|
}
|
|
|
|
// fits returns whether the cache fits more entries.
|
|
func (c *Cache) fits() bool {
|
|
return c.size > len(c.entries)
|
|
}
|