Add LRU cache
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Tyler 2019-10-05 16:56:24 -04:00
parent 5306bdbb7e
commit d1393164a5
7 changed files with 176 additions and 10 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea/
*.iml

View File

@ -14,6 +14,7 @@ const (
Memcache = "memcache"
Redis = "redis"
Memory = "memory"
Lru = "lru"
)
var (
@ -66,6 +67,20 @@ func New(uri string) (CacheInterface, error) {
}
return NewMemoryCache(time.Duration(i) * time.Second)
case Lru:
size := query.Get("size")
if size == "" {
size = "128"
}
i, err := strconv.Atoi(size)
if err != nil {
return nil, err
}
return NewLruCache(i)
}
return nil, ErrInvalidDriver

1
go.mod
View File

@ -4,6 +4,7 @@ go 1.12
require (
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b
github.com/hashicorp/golang-lru v0.5.3
github.com/hoisie/redis v0.0.0-20160730154456-b5c6e81454e0
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/vmihailenco/msgpack/v4 v4.2.0

2
go.sum
View File

@ -3,6 +3,8 @@ github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQ
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hoisie/redis v0.0.0-20160730154456-b5c6e81454e0 h1:mjZV3MTu2A5gwfT5G9IIiLGdwZNciyVq5qqnmJJZ2JI=
github.com/hoisie/redis v0.0.0-20160730154456-b5c6e81454e0/go.mod h1:pMYMxVaKJqCDC1JUg/XbPJ4/fSazB25zORpFzqsIGIc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=

46
lru.go Normal file
View File

@ -0,0 +1,46 @@
package cache
import (
"github.com/hashicorp/golang-lru"
"time"
)
type LruCache struct {
c *lru.Cache
}
func NewLruCache(size int) (CacheInterface, error) {
c, err := lru.New(size)
if err != nil {
return nil, err
}
return &LruCache{c: c}, nil
}
func (mc *LruCache) Has(key string) bool {
_, exists := mc.c.Get(key)
return exists
}
func (mc *LruCache) Get(key string, dst ...interface{}) ([]byte, error) {
item, exists := mc.c.Get(key)
if !exists {
return nil, ErrMemoryCacheNotExists
}
return memoryCacheGet(item, dst...)
}
func (mc *LruCache) Set(key string, val interface{}, ttl time.Duration) error {
mc.c.Add(key, val)
return nil
}
func (mc *LruCache) Del(key string) error {
mc.c.Remove(key)
return nil
}

96
lru_test.go Normal file
View File

@ -0,0 +1,96 @@
package cache
import (
"testing"
"time"
)
func TestNew_LruURI(t *testing.T) {
cache, err := New("lru://")
if err != nil {
t.Fatal("Error creating cache:", err)
}
if _, ok := cache.(*LruCache); !ok {
t.Fatal("Cache is not instance of MemoryCache")
}
}
func TestLruCache_Get(t *testing.T) {
cache, err := New("lru://")
if err != nil {
t.Fatal("Error creating cache:", err)
}
obj := "test"
cache.Set("test", obj, time.Minute)
var new string
cache.Get("test", &new)
if obj != new {
t.Fatal("Expected", obj, "got", new)
}
}
func TestLruCache_GetRaw(t *testing.T) {
cache, err := New("lru://")
if err != nil {
t.Fatal("Error creating cache:", err)
}
obj := "test"
cache.Set("test", obj, time.Minute)
v, err := cache.Get("test")
if err != nil {
t.Fatal("Unable to get value:", err)
}
new := string(v)
if obj != new {
t.Fatal("Expected", obj, "got", new)
}
}
func TestLruCache_Has(t *testing.T) {
cache, err := New("lru://")
if err != nil {
t.Fatal("Error creating cache:", err)
}
cache.Set("test", "test", time.Minute)
if !cache.Has("test") {
t.Fatal("Expected cache to have object 'test'")
}
}
func TestLruCache_Del(t *testing.T) {
cache, err := New("lru://")
if err != nil {
t.Fatal("Error creating cache:", err)
}
cache.Set("test", "test", time.Minute)
if !cache.Has("test") {
t.Fatal("Expected cache to have object 'test'")
}
cache.Del("test")
if cache.Has("test") {
t.Fatal("Cache did not properly delete item")
}
}

View File

@ -35,6 +35,20 @@ func (mc *MemoryCache) Get(key string, dst ...interface{}) ([]byte, error) {
return nil, ErrMemoryCacheNotExists
}
return memoryCacheGet(item, dst...)
}
func (mc *MemoryCache) Set(key string, val interface{}, ttl time.Duration) error {
mc.c.Set(key, val, ttl)
return nil
}
func (mc *MemoryCache) Del(key string) error {
mc.c.Delete(key)
return nil
}
func memoryCacheGet(item interface{}, dst ...interface{}) ([]byte, error) {
if len(dst) == 0 {
switch item.(type) {
case string:
@ -165,13 +179,3 @@ func (mc *MemoryCache) Get(key string, dst ...interface{}) ([]byte, error) {
return nil, nil
}
func (mc *MemoryCache) Set(key string, val interface{}, ttl time.Duration) error {
mc.c.Set(key, val, ttl)
return nil
}
func (mc *MemoryCache) Del(key string) error {
mc.c.Delete(key)
return nil
}