|
|
|
@ -8,7 +8,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
package main
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import "container/list"
|
|
|
|
import (
|
|
|
|
|
|
|
|
"container/list"
|
|
|
|
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var mu sync.Mutex
|
|
|
|
|
|
|
|
|
|
|
|
// CacheSize determines how big the cache can grow
|
|
|
|
// CacheSize determines how big the cache can grow
|
|
|
|
const CacheSize = 100
|
|
|
|
const CacheSize = 100
|
|
|
|
@ -41,12 +46,18 @@ func New(load KeyStoreCacheLoader) *KeyStoreCache {
|
|
|
|
|
|
|
|
|
|
|
|
// Get gets the key from cache, loads it from the source if needed
|
|
|
|
// Get gets the key from cache, loads it from the source if needed
|
|
|
|
func (k *KeyStoreCache) Get(key string) string {
|
|
|
|
func (k *KeyStoreCache) Get(key string) string {
|
|
|
|
|
|
|
|
mu.Lock()
|
|
|
|
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
|
|
|
|
|
|
|
if e, ok := k.cache[key]; ok {
|
|
|
|
if e, ok := k.cache[key]; ok {
|
|
|
|
k.pages.MoveToFront(e)
|
|
|
|
k.pages.MoveToFront(e)
|
|
|
|
return e.Value.(page).Value
|
|
|
|
value := e.Value.(page).Value
|
|
|
|
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Miss - load from database and save it in cache
|
|
|
|
// Miss - load from database and save it in cache
|
|
|
|
p := page{key, k.load(key)}
|
|
|
|
p := page{key, k.load(key)}
|
|
|
|
|
|
|
|
|
|
|
|
// if cache is full remove the least used item
|
|
|
|
// if cache is full remove the least used item
|
|
|
|
if len(k.cache) >= CacheSize {
|
|
|
|
if len(k.cache) >= CacheSize {
|
|
|
|
end := k.pages.Back()
|
|
|
|
end := k.pages.Back()
|
|
|
|
@ -57,6 +68,7 @@ func (k *KeyStoreCache) Get(key string) string {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
k.pages.PushFront(p)
|
|
|
|
k.pages.PushFront(p)
|
|
|
|
k.cache[key] = k.pages.Front()
|
|
|
|
k.cache[key] = k.pages.Front()
|
|
|
|
|
|
|
|
|
|
|
|
return p.Value
|
|
|
|
return p.Value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|