You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
smallstep-certificates/authority/cache/cache.go

90 lines
1.6 KiB
Go

package cache
import (
"context"
"errors"
"sync"
)
var ErrNotFound = errors.New("not found")
type Cache interface {
Get(context.Context, string) ([]byte, error)
Set(context.Context, string, []byte) error
Delete(context.Context, string) error
}
type Getter interface {
Get(ctx context.Context, key string) ([]byte, error)
}
// A GetterFunc implements Getter with a function.
type GetterFunc func(ctx context.Context, key string) ([]byte, error)
func (f GetterFunc) Get(ctx context.Context, key string) ([]byte, error) {
return f(ctx, key)
}
type Pool interface {
New(name string, getter Getter) Cache
Get(name string) (Cache, bool)
}
func DefaultPool() Pool {
return &defaultPool{
caches: make(map[string]Cache),
}
}
type defaultPool struct {
mu sync.RWMutex
caches map[string]Cache
}
func (p *defaultPool) New(name string, getter Getter) Cache {
c := &mapCache{
m: new(sync.Map),
getter: getter,
}
p.mu.Lock()
p.caches[name] = c
p.mu.Unlock()
return c
}
func (p *defaultPool) Get(name string) (Cache, bool) {
p.mu.RLock()
c, ok := p.caches[name]
p.mu.RUnlock()
return c, ok
}
type mapCache struct {
name string
m *sync.Map
getter Getter
}
func (m *mapCache) Get(ctx context.Context, key string) ([]byte, error) {
v, ok := m.m.Load(key)
if !ok {
b, err := m.getter.Get(ctx, key)
if err != nil {
return nil, err
}
m.m.Store(key, b)
return b, nil
}
return v.([]byte), nil
}
func (m *mapCache) Set(ctx context.Context, key string, value []byte) error {
m.m.Store(key, value)
return nil
}
func (m *mapCache) Delete(ctx context.Context, key string) error {
m.m.Delete(key)
return nil
}