119 lines
2.8 KiB
Go
119 lines
2.8 KiB
Go
// Copyright (c) 2013 CloudFlare, Inc.
|
|
|
|
package lrucache
|
|
|
|
import (
|
|
"hash/crc32"
|
|
"time"
|
|
)
|
|
|
|
// MultiLRUCache data structure. Never dereference it or copy it by
|
|
// value. Always use it through a pointer.
|
|
type MultiLRUCache struct {
|
|
buckets uint
|
|
cache []*LRUCache
|
|
}
|
|
|
|
// Using this constructor is almost always wrong. Use NewMultiLRUCache instead.
|
|
func (m *MultiLRUCache) Init(buckets, bucket_capacity uint) {
|
|
m.buckets = buckets
|
|
m.cache = make([]*LRUCache, buckets)
|
|
for i := uint(0); i < buckets; i++ {
|
|
m.cache[i] = NewLRUCache(bucket_capacity)
|
|
}
|
|
}
|
|
|
|
// Set the stale expiry grace period for each cache in the multicache instance.
|
|
func (m *MultiLRUCache) SetExpireGracePeriod(p time.Duration) {
|
|
for _, c := range m.cache {
|
|
c.ExpireGracePeriod = p
|
|
}
|
|
}
|
|
|
|
func NewMultiLRUCache(buckets, bucket_capacity uint) *MultiLRUCache {
|
|
m := &MultiLRUCache{}
|
|
m.Init(buckets, bucket_capacity)
|
|
return m
|
|
}
|
|
|
|
func (m *MultiLRUCache) bucketNo(key string) uint {
|
|
// Arbitrary choice. Any fast hash will do.
|
|
return uint(crc32.ChecksumIEEE([]byte(key))) % m.buckets
|
|
}
|
|
|
|
func (m *MultiLRUCache) Set(key string, value interface{}, expire time.Time) {
|
|
m.cache[m.bucketNo(key)].Set(key, value, expire)
|
|
}
|
|
|
|
func (m *MultiLRUCache) SetNow(key string, value interface{}, expire time.Time, now time.Time) {
|
|
m.cache[m.bucketNo(key)].SetNow(key, value, expire, now)
|
|
}
|
|
|
|
func (m *MultiLRUCache) Get(key string) (value interface{}, ok bool) {
|
|
return m.cache[m.bucketNo(key)].Get(key)
|
|
}
|
|
|
|
func (m *MultiLRUCache) GetQuiet(key string) (value interface{}, ok bool) {
|
|
return m.cache[m.bucketNo(key)].Get(key)
|
|
}
|
|
|
|
func (m *MultiLRUCache) GetNotStale(key string) (value interface{}, ok bool) {
|
|
return m.cache[m.bucketNo(key)].GetNotStale(key)
|
|
}
|
|
|
|
func (m *MultiLRUCache) GetNotStaleNow(key string, now time.Time) (value interface{}, ok bool) {
|
|
return m.cache[m.bucketNo(key)].GetNotStaleNow(key, now)
|
|
}
|
|
|
|
func (m *MultiLRUCache) GetStale(key string) (value interface{}, ok, expired bool) {
|
|
return m.cache[m.bucketNo(key)].GetStale(key)
|
|
}
|
|
|
|
func (m *MultiLRUCache) GetStaleNow(key string, now time.Time) (value interface{}, ok, expired bool) {
|
|
return m.cache[m.bucketNo(key)].GetStaleNow(key, now)
|
|
}
|
|
|
|
func (m *MultiLRUCache) Del(key string) (value interface{}, ok bool) {
|
|
return m.cache[m.bucketNo(key)].Del(key)
|
|
}
|
|
|
|
func (m *MultiLRUCache) Clear() int {
|
|
var s int
|
|
for _, c := range m.cache {
|
|
s += c.Clear()
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (m *MultiLRUCache) Len() int {
|
|
var s int
|
|
for _, c := range m.cache {
|
|
s += c.Len()
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (m *MultiLRUCache) Capacity() int {
|
|
var s int
|
|
for _, c := range m.cache {
|
|
s += c.Capacity()
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (m *MultiLRUCache) Expire() int {
|
|
var s int
|
|
for _, c := range m.cache {
|
|
s += c.Expire()
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (m *MultiLRUCache) ExpireNow(now time.Time) int {
|
|
var s int
|
|
for _, c := range m.cache {
|
|
s += c.ExpireNow(now)
|
|
}
|
|
return s
|
|
}
|