mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-25 22:42:16 -05:00
96 lines
1.7 KiB
Go
96 lines
1.7 KiB
Go
package cache
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Entry represents an entry on the cache. You can type assert on V.
|
|
type Entry struct {
|
|
V interface{}
|
|
Valid bool
|
|
}
|
|
|
|
// Cache is a barebones cache implementation.
|
|
type Cache struct {
|
|
entries map[string]map[string]Entry
|
|
size int
|
|
ttl time.Duration
|
|
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]map[string]Entry{},
|
|
}
|
|
}
|
|
|
|
// Get gets an entry on a service `svcKey` by a give `key`.
|
|
func (c *Cache) Get(svcKey, key string) (*Entry, error) {
|
|
var value Entry
|
|
ok := true
|
|
|
|
c.m.Lock()
|
|
defer c.m.Unlock()
|
|
|
|
if value, ok = c.entries[svcKey][key]; !ok {
|
|
return nil, fmt.Errorf("invalid service key: `%v`", key)
|
|
}
|
|
|
|
return &value, nil
|
|
}
|
|
|
|
// Set sets a key / value. It lets a service add entries on a request basis.
|
|
func (c *Cache) Set(svcKey, key string, val interface{}) error {
|
|
c.m.Lock()
|
|
defer c.m.Unlock()
|
|
|
|
if !c.fits() {
|
|
return fmt.Errorf("cache is full")
|
|
}
|
|
|
|
if _, ok := c.entries[svcKey]; !ok {
|
|
c.entries[svcKey] = map[string]Entry{}
|
|
}
|
|
|
|
if _, ok := c.entries[svcKey][key]; ok {
|
|
return fmt.Errorf("key `%v` already exists", key)
|
|
}
|
|
|
|
c.entries[svcKey][key] = Entry{
|
|
V: val,
|
|
Valid: true,
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Invalidate invalidates a cache Entry by key.
|
|
func (c *Cache) Invalidate(key string) error {
|
|
c.m.Lock()
|
|
defer c.m.Unlock()
|
|
|
|
if _, ok := c.entries[key]; !ok {
|
|
return fmt.Errorf("invalid key: `%v`", key)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Length returns the amount of entries.
|
|
func (c *Cache) Length(k string) int {
|
|
return len(c.entries[k])
|
|
}
|
|
|
|
func (c *Cache) fits() bool {
|
|
if c.size < len(c.entries) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|