Chromium Code Reviews| Index: go/util/caching.go |
| diff --git a/go/util/caching.go b/go/util/caching.go |
| index da820115cbbff5a8583729d9dff4ec659360b9a7..a3ba164c9008ca345e28a5587d49f27987a80178 100644 |
| --- a/go/util/caching.go |
| +++ b/go/util/caching.go |
| @@ -22,6 +22,9 @@ type LRUCache interface { |
| // Remove removes a key value pair from the cache. |
| Remove(key interface{}) |
| + |
| + // Keys returns all the keys in the LRUCache. |
| + Keys() []interface{} |
| } |
| // LRUCodec converts serializes/deserializes an instance of a type to/from |
| @@ -37,19 +40,41 @@ type LRUCodec interface { |
| type MemLRUCache struct { |
| cache *lru.Cache |
| + keys map[string]bool |
| mutex sync.RWMutex |
| } |
| func NewMemLRUCache(maxEntries int) *MemLRUCache { |
| - return &MemLRUCache{ |
| + ret := &MemLRUCache{ |
| cache: lru.New(maxEntries), |
| + keys: map[string]bool{}, |
| + } |
| + |
| + ret.cache.OnEvicted = func(key lru.Key, value interface{}) { |
| + delete(ret.keys, getStringKey(key)) |
| + } |
| + |
| + return ret |
| +} |
| + |
| +func getStringKey(key interface{}) string { |
| + k := "" |
| + switch key := key.(type) { |
| + case string: |
| + k = key |
| + case []byte: |
| + if key != nil { |
| + k = string(key) |
| + } |
| } |
| + return k |
| } |
| func (m *MemLRUCache) Add(key, value interface{}) bool { |
| m.mutex.Lock() |
| defer m.mutex.Unlock() |
| m.cache.Add(key, value) |
| + m.keys[getStringKey(key)] = true |
| return true |
| } |
| @@ -68,6 +93,18 @@ func (m *MemLRUCache) Len() int { |
| func (m *MemLRUCache) Remove(key interface{}) { |
| m.mutex.Lock() |
| defer m.mutex.Unlock() |
| + m.cache.Remove(key) |
| + delete(m.keys, getStringKey(key)) |
| +} |
| + |
| +func (m *MemLRUCache) Keys() []interface{} { |
|
jcgregorio
2015/10/13 18:40:24
Needs unit tests.
stephana
2015/10/14 14:26:30
Done. I factored out tests from redisutils to be a
|
| + m.mutex.RLock() |
| + m.mutex.RUnlock() |
|
jcgregorio
2015/10/13 18:40:24
defer m.mutex.RUnlock()
stephana
2015/10/14 14:26:30
Good catch. Fixed.
|
| + ret := make([]interface{}, 0, len(m.keys)) |
| + for k := range m.keys { |
| + ret = append(ret, k) |
| + } |
| + return ret |
| } |
| type jsonCodec struct { |