1 // Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
2 // Revel Framework source code and usage is governed by a MIT style
3 // license that can be found in the LICENSE file.
12 "github.com/patrickmn/go-cache"
16 type InMemoryCache struct {
17 cache cache.Cache // Only expose the methods we want to make available
18 mu sync.RWMutex // For increment / decrement prevent reads and writes
21 func NewInMemoryCache(defaultExpiration time.Duration) InMemoryCache {
22 return InMemoryCache{cache: *cache.New(defaultExpiration, time.Minute), mu: sync.RWMutex{}}
25 func (c InMemoryCache) Get(key string, ptrValue interface{}) error {
29 value, found := c.cache.Get(key)
34 v := reflect.ValueOf(ptrValue)
35 if v.Type().Kind() == reflect.Ptr && v.Elem().CanSet() {
36 v.Elem().Set(reflect.ValueOf(value))
40 err := fmt.Errorf("revel/cache: attempt to get %s, but can not set value %v", key, v)
41 cacheLog.Error(err.Error())
45 func (c InMemoryCache) GetMulti(keys ...string) (Getter, error) {
49 func (c InMemoryCache) Set(key string, value interface{}, expires time.Duration) error {
52 // NOTE: go-cache understands the values of DefaultExpiryTime and ForEverNeverExpiry
53 c.cache.Set(key, value, expires)
57 func (c InMemoryCache) Add(key string, value interface{}, expires time.Duration) error {
60 err := c.cache.Add(key, value, expires)
67 func (c InMemoryCache) Replace(key string, value interface{}, expires time.Duration) error {
70 if err := c.cache.Replace(key, value, expires); err != nil {
76 func (c InMemoryCache) Delete(key string) error {
79 if _, found := c.cache.Get(key); !found {
86 func (c InMemoryCache) Increment(key string, n uint64) (newValue uint64, err error) {
89 if _, found := c.cache.Get(key); !found {
90 return 0, ErrCacheMiss
92 if err = c.cache.Increment(key, int64(n)); err != nil {
96 return c.convertTypeToUint64(key)
99 func (c InMemoryCache) Decrement(key string, n uint64) (newValue uint64, err error) {
102 if nv, err := c.convertTypeToUint64(key); err != nil {
105 // Stop from going below zero
110 if err = c.cache.Decrement(key, int64(n)); err != nil {
114 return c.convertTypeToUint64(key)
117 func (c InMemoryCache) Flush() error {
125 // Fetches and returns the converted type to a uint64
126 func (c InMemoryCache) convertTypeToUint64(key string) (newValue uint64, err error) {
127 v, found := c.cache.Get(key)
129 return newValue, ErrCacheMiss
134 newValue = uint64(v.(int))
136 newValue = uint64(v.(int8))
138 newValue = uint64(v.(int16))
140 newValue = uint64(v.(int32))
142 newValue = uint64(v.(int64))
144 newValue = uint64(v.(uint))
146 newValue = uint64(v.(uintptr))
148 newValue = uint64(v.(uint8))
150 newValue = uint64(v.(uint16))
152 newValue = uint64(v.(uint32))
154 newValue = uint64(v.(uint64))
156 newValue = uint64(v.(float32))
158 newValue = uint64(v.(float64))
160 err = ErrInvalidValue