Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: go/util/caching.go

Issue 1401563003: Enable clear/purge for failed digests (Closed) Base URL: https://skia.googlesource.com/buildbot@master
Patch Set: Added unit test to FileDiffStore Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « go/redisutil/redisutil_test.go ('k') | go/util/caching_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 package util 1 package util
2 2
3 import ( 3 import (
4 "encoding/json" 4 "encoding/json"
5 "reflect" 5 "reflect"
6 "sync" 6 "sync"
7 7
8 "github.com/golang/groupcache/lru" 8 "github.com/golang/groupcache/lru"
9 ) 9 )
10 10
11 // Generic LRUCache interface. 11 // Generic LRUCache interface.
12 type LRUCache interface { 12 type LRUCache interface {
13 // Add adds a key-value pair to the cache. 13 // Add adds a key-value pair to the cache.
14 Add(key, value interface{}) bool 14 Add(key, value interface{}) bool
15 15
16 // Get returns a key value for the given cache. If ok is true 16 // Get returns a key value for the given cache. If ok is true
17 // the fetch was succesfull. 17 // the fetch was succesfull.
18 Get(key interface{}) (value interface{}, ok bool) 18 Get(key interface{}) (value interface{}, ok bool)
19 19
20 // Len returns the current size of the cache. 20 // Len returns the current size of the cache.
21 Len() int 21 Len() int
22 22
23 // Remove removes a key value pair from the cache. 23 // Remove removes a key value pair from the cache.
24 Remove(key interface{}) 24 Remove(key interface{})
25
26 // Keys returns all the keys in the LRUCache.
27 Keys() []interface{}
25 } 28 }
26 29
27 // LRUCodec converts serializes/deserializes an instance of a type to/from 30 // LRUCodec converts serializes/deserializes an instance of a type to/from
28 // byte arrays. Encode and Decode have to be the inverse of each other. 31 // byte arrays. Encode and Decode have to be the inverse of each other.
29 type LRUCodec interface { 32 type LRUCodec interface {
30 // Encode serializes the given value to a byte array (inverse of Decode) . 33 // Encode serializes the given value to a byte array (inverse of Decode) .
31 Encode(interface{}) ([]byte, error) 34 Encode(interface{}) ([]byte, error)
32 35
33 // Decode deserializes the byte array to an instance of the type that 36 // Decode deserializes the byte array to an instance of the type that
34 // was passed to Encode in a prior call. 37 // was passed to Encode in a prior call.
35 Decode([]byte) (interface{}, error) 38 Decode([]byte) (interface{}, error)
36 } 39 }
37 40
38 type MemLRUCache struct { 41 type MemLRUCache struct {
39 cache *lru.Cache 42 cache *lru.Cache
43 keys map[string]bool
40 mutex sync.RWMutex 44 mutex sync.RWMutex
41 } 45 }
42 46
43 func NewMemLRUCache(maxEntries int) *MemLRUCache { 47 func NewMemLRUCache(maxEntries int) *MemLRUCache {
44 » return &MemLRUCache{ 48 » ret := &MemLRUCache{
45 cache: lru.New(maxEntries), 49 cache: lru.New(maxEntries),
50 keys: map[string]bool{},
46 } 51 }
52
53 ret.cache.OnEvicted = func(key lru.Key, value interface{}) {
54 delete(ret.keys, getStringKey(key))
55 }
56
57 return ret
58 }
59
60 func getStringKey(key interface{}) string {
61 k := ""
62 switch key := key.(type) {
63 case string:
64 k = key
65 case []byte:
66 if key != nil {
67 k = string(key)
68 }
69 }
70 return k
47 } 71 }
48 72
49 func (m *MemLRUCache) Add(key, value interface{}) bool { 73 func (m *MemLRUCache) Add(key, value interface{}) bool {
50 m.mutex.Lock() 74 m.mutex.Lock()
51 defer m.mutex.Unlock() 75 defer m.mutex.Unlock()
52 m.cache.Add(key, value) 76 m.cache.Add(key, value)
77 m.keys[getStringKey(key)] = true
53 return true 78 return true
54 } 79 }
55 80
56 func (m *MemLRUCache) Get(key interface{}) (value interface{}, ok bool) { 81 func (m *MemLRUCache) Get(key interface{}) (value interface{}, ok bool) {
57 m.mutex.RLock() 82 m.mutex.RLock()
58 m.mutex.RUnlock() 83 m.mutex.RUnlock()
59 return m.cache.Get(key) 84 return m.cache.Get(key)
60 } 85 }
61 86
62 func (m *MemLRUCache) Len() int { 87 func (m *MemLRUCache) Len() int {
63 m.mutex.RLock() 88 m.mutex.RLock()
64 m.mutex.RUnlock() 89 m.mutex.RUnlock()
65 return m.cache.Len() 90 return m.cache.Len()
66 } 91 }
67 92
68 func (m *MemLRUCache) Remove(key interface{}) { 93 func (m *MemLRUCache) Remove(key interface{}) {
69 m.mutex.Lock() 94 m.mutex.Lock()
70 defer m.mutex.Unlock() 95 defer m.mutex.Unlock()
96 m.cache.Remove(key)
97 delete(m.keys, getStringKey(key))
98 }
99
100 func (m *MemLRUCache) Keys() []interface{} {
101 m.mutex.RLock()
102 defer m.mutex.RUnlock()
103 ret := make([]interface{}, 0, len(m.keys))
104 for k := range m.keys {
105 ret = append(ret, k)
106 }
107 return ret
71 } 108 }
72 109
73 type jsonCodec struct { 110 type jsonCodec struct {
74 targetType reflect.Type 111 targetType reflect.Type
75 isSlice bool 112 isSlice bool
76 } 113 }
77 114
78 // JSONCodec implements the LRUCodec interface by serializing and 115 // JSONCodec implements the LRUCodec interface by serializing and
79 // deserializing instances of the underlying type of 'instance'. 116 // deserializing instances of the underlying type of 'instance'.
80 // Generally it's assumed that 'instance' is a struct, a pointer to 117 // Generally it's assumed that 'instance' is a struct, a pointer to
(...skipping 20 matching lines...) Expand all
101 ret := reflect.New(j.targetType).Interface() 138 ret := reflect.New(j.targetType).Interface()
102 err := json.Unmarshal(byteData, ret) 139 err := json.Unmarshal(byteData, ret)
103 if err != nil { 140 if err != nil {
104 return nil, err 141 return nil, err
105 } else if j.isSlice { 142 } else if j.isSlice {
106 return reflect.ValueOf(ret).Elem().Interface(), nil 143 return reflect.ValueOf(ret).Elem().Interface(), nil
107 } 144 }
108 145
109 return ret, nil 146 return ret, nil
110 } 147 }
OLDNEW
« no previous file with comments | « go/redisutil/redisutil_test.go ('k') | go/util/caching_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698