1
16
17 package driver
18
19 import (
20 "strconv"
21 "strings"
22 "sync"
23
24 rspb "helm.sh/helm/v3/pkg/release"
25 )
26
27 var _ Driver = (*Memory)(nil)
28
29 const (
30
31 MemoryDriverName = "Memory"
32
33 defaultNamespace = "default"
34 )
35
36
37 type memReleases map[string]records
38
39
40 type Memory struct {
41 sync.RWMutex
42 namespace string
43
44 cache map[string]memReleases
45 }
46
47
48 func NewMemory() *Memory {
49 return &Memory{cache: map[string]memReleases{}, namespace: "default"}
50 }
51
52
53
54 func (mem *Memory) SetNamespace(ns string) {
55 mem.namespace = ns
56 }
57
58
59 func (mem *Memory) Name() string {
60 return MemoryDriverName
61 }
62
63
64 func (mem *Memory) Get(key string) (*rspb.Release, error) {
65 defer unlock(mem.rlock())
66
67 keyWithoutPrefix := strings.TrimPrefix(key, "sh.helm.release.v1.")
68 switch elems := strings.Split(keyWithoutPrefix, ".v"); len(elems) {
69 case 2:
70 name, ver := elems[0], elems[1]
71 if _, err := strconv.Atoi(ver); err != nil {
72 return nil, ErrInvalidKey
73 }
74 if recs, ok := mem.cache[mem.namespace][name]; ok {
75 if r := recs.Get(key); r != nil {
76 return r.rls, nil
77 }
78 }
79 return nil, ErrReleaseNotFound
80 default:
81 return nil, ErrInvalidKey
82 }
83 }
84
85
86 func (mem *Memory) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) {
87 defer unlock(mem.rlock())
88
89 var ls []*rspb.Release
90 for namespace := range mem.cache {
91 if mem.namespace != "" {
92
93 namespace = mem.namespace
94 }
95 for _, recs := range mem.cache[namespace] {
96 recs.Iter(func(_ int, rec *record) bool {
97 if filter(rec.rls) {
98 ls = append(ls, rec.rls)
99 }
100 return true
101 })
102 }
103 if mem.namespace != "" {
104
105 break
106 }
107 }
108 return ls, nil
109 }
110
111
112 func (mem *Memory) Query(keyvals map[string]string) ([]*rspb.Release, error) {
113 defer unlock(mem.rlock())
114
115 var lbs labels
116
117 lbs.init()
118 lbs.fromMap(keyvals)
119
120 var ls []*rspb.Release
121 for namespace := range mem.cache {
122 if mem.namespace != "" {
123
124 namespace = mem.namespace
125 }
126 for _, recs := range mem.cache[namespace] {
127 recs.Iter(func(_ int, rec *record) bool {
128
129
130 if rec == nil {
131 return false
132 }
133 if rec.lbs.match(lbs) {
134 ls = append(ls, rec.rls)
135 }
136 return true
137 })
138 }
139 if mem.namespace != "" {
140
141 break
142 }
143 }
144
145 if len(ls) == 0 {
146 return nil, ErrReleaseNotFound
147 }
148
149 return ls, nil
150 }
151
152
153 func (mem *Memory) Create(key string, rls *rspb.Release) error {
154 defer unlock(mem.wlock())
155
156
157 namespace := rls.Namespace
158 if namespace == "" {
159 namespace = defaultNamespace
160 }
161 mem.SetNamespace(namespace)
162
163 if _, ok := mem.cache[namespace]; !ok {
164 mem.cache[namespace] = memReleases{}
165 }
166
167 if recs, ok := mem.cache[namespace][rls.Name]; ok {
168 if err := recs.Add(newRecord(key, rls)); err != nil {
169 return err
170 }
171 mem.cache[namespace][rls.Name] = recs
172 return nil
173 }
174 mem.cache[namespace][rls.Name] = records{newRecord(key, rls)}
175 return nil
176 }
177
178
179 func (mem *Memory) Update(key string, rls *rspb.Release) error {
180 defer unlock(mem.wlock())
181
182
183 namespace := rls.Namespace
184 if namespace == "" {
185 namespace = defaultNamespace
186 }
187 mem.SetNamespace(namespace)
188
189 if _, ok := mem.cache[namespace]; ok {
190 if rs, ok := mem.cache[namespace][rls.Name]; ok && rs.Exists(key) {
191 rs.Replace(key, newRecord(key, rls))
192 return nil
193 }
194 }
195 return ErrReleaseNotFound
196 }
197
198
199 func (mem *Memory) Delete(key string) (*rspb.Release, error) {
200 defer unlock(mem.wlock())
201
202 keyWithoutPrefix := strings.TrimPrefix(key, "sh.helm.release.v1.")
203 elems := strings.Split(keyWithoutPrefix, ".v")
204
205 if len(elems) != 2 {
206 return nil, ErrInvalidKey
207 }
208
209 name, ver := elems[0], elems[1]
210 if _, err := strconv.Atoi(ver); err != nil {
211 return nil, ErrInvalidKey
212 }
213 if _, ok := mem.cache[mem.namespace]; ok {
214 if recs, ok := mem.cache[mem.namespace][name]; ok {
215 if r := recs.Remove(key); r != nil {
216
217 mem.cache[mem.namespace][name] = recs
218 return r.rls, nil
219 }
220 }
221 }
222 return nil, ErrReleaseNotFound
223 }
224
225
226 func (mem *Memory) wlock() func() {
227 mem.Lock()
228 return func() { mem.Unlock() }
229 }
230
231
232 func (mem *Memory) rlock() func() {
233 mem.RLock()
234 return func() { mem.RUnlock() }
235 }
236
237
238
239
240 func unlock(fn func()) { fn() }
241
View as plain text