74 lines
1.4 KiB
Go
74 lines
1.4 KiB
Go
package ccache
|
|
|
|
import (
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
type bucket struct {
|
|
sync.RWMutex
|
|
lookup map[string]*Item
|
|
}
|
|
|
|
func (b *bucket) get(key string) *Item {
|
|
b.RLock()
|
|
defer b.RUnlock()
|
|
return b.lookup[key]
|
|
}
|
|
|
|
func (b *bucket) set(key string, value interface{}, duration time.Duration) (*Item, bool, int64) {
|
|
expires := time.Now().Add(duration).Unix()
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
if existing, exists := b.lookup[key]; exists {
|
|
existing.value = value
|
|
existing.expires = expires
|
|
d := int64(0)
|
|
if sized, ok := value.(Sized); ok {
|
|
newSize := sized.Size()
|
|
d = newSize - existing.size
|
|
if d != 0 {
|
|
atomic.StoreInt64(&existing.size, newSize)
|
|
}
|
|
}
|
|
return existing, false, int64(d)
|
|
}
|
|
item := newItem(key, value, expires)
|
|
b.lookup[key] = item
|
|
return item, true, int64(item.size)
|
|
}
|
|
|
|
func (b *bucket) replace(key string, value interface{}) (bool, int64) {
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
existing, exists := b.lookup[key]
|
|
if exists == false {
|
|
return false, 0
|
|
}
|
|
d := int64(0)
|
|
if sized, ok := value.(Sized); ok {
|
|
newSize := sized.Size()
|
|
d = newSize - existing.size
|
|
if d != 0 {
|
|
atomic.StoreInt64(&existing.size, newSize)
|
|
}
|
|
}
|
|
existing.value = value
|
|
return true, d
|
|
}
|
|
|
|
func (b *bucket) delete(key string) *Item {
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
item := b.lookup[key]
|
|
delete(b.lookup, key)
|
|
return item
|
|
}
|
|
|
|
func (b *bucket) clear() {
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
b.lookup = make(map[string]*Item)
|
|
}
|