github.com/felipejfc/helm@v2.1.2+incompatible/pkg/storage/driver/memory.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package driver 18 19 import ( 20 "bytes" 21 "fmt" 22 "io" 23 "strconv" 24 "strings" 25 "sync" 26 27 rspb "k8s.io/helm/pkg/proto/hapi/release" 28 ) 29 30 var _ Driver = (*Memory)(nil) 31 32 // MemoryDriverName is the string name of this driver. 33 const MemoryDriverName = "Memory" 34 35 // Memory is the in-memory storage driver implementation. 36 type Memory struct { 37 sync.RWMutex 38 cache map[string]records 39 } 40 41 // NewMemory initializes a new memory driver. 42 func NewMemory() *Memory { 43 return &Memory{cache: map[string]records{}} 44 } 45 46 // Name returns the name of the driver. 47 func (mem *Memory) Name() string { 48 return MemoryDriverName 49 } 50 51 // Get returns the release named by key or returns ErrReleaseNotFound. 52 func (mem *Memory) Get(key string) (*rspb.Release, error) { 53 defer unlock(mem.rlock()) 54 55 switch elems := strings.Split(key, ".v"); len(elems) { 56 case 2: 57 name, ver := elems[0], elems[1] 58 if _, err := strconv.Atoi(ver); err != nil { 59 return nil, ErrInvalidKey 60 } 61 if recs, ok := mem.cache[name]; ok { 62 if r := recs.Get(key); r != nil { 63 return r.rls, nil 64 } 65 } 66 return nil, ErrReleaseNotFound 67 default: 68 return nil, ErrInvalidKey 69 } 70 } 71 72 // List returns the list of all releases such that filter(release) == true 73 func (mem *Memory) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) { 74 defer unlock(mem.rlock()) 75 76 var ls []*rspb.Release 77 for _, recs := range mem.cache { 78 recs.Iter(func(_ int, rec *record) bool { 79 if filter(rec.rls) { 80 ls = append(ls, rec.rls) 81 } 82 return true 83 }) 84 } 85 return ls, nil 86 } 87 88 // Query returns the set of releases that match the provided set of labels 89 func (mem *Memory) Query(keyvals map[string]string) ([]*rspb.Release, error) { 90 defer unlock(mem.rlock()) 91 92 var lbs labels 93 94 lbs.init() 95 lbs.fromMap(keyvals) 96 97 var ls []*rspb.Release 98 for _, recs := range mem.cache { 99 recs.Iter(func(_ int, rec *record) bool { 100 if rec.lbs.match(lbs) { 101 ls = append(ls, rec.rls) 102 } 103 return true 104 }) 105 } 106 return ls, nil 107 } 108 109 // Create creates a new release or returns ErrReleaseExists. 110 func (mem *Memory) Create(key string, rls *rspb.Release) error { 111 defer unlock(mem.wlock()) 112 113 if recs, ok := mem.cache[rls.Name]; ok { 114 if err := recs.Add(newRecord(key, rls)); err != nil { 115 return err 116 } 117 mem.cache[rls.Name] = recs 118 return nil 119 } 120 mem.cache[rls.Name] = records{newRecord(key, rls)} 121 return nil 122 } 123 124 // Update updates a release or returns ErrReleaseNotFound. 125 func (mem *Memory) Update(key string, rls *rspb.Release) error { 126 defer unlock(mem.wlock()) 127 128 if rs, ok := mem.cache[rls.Name]; ok && rs.Exists(key) { 129 rs.Replace(key, newRecord(key, rls)) 130 return nil 131 } 132 return ErrReleaseNotFound 133 } 134 135 // Delete deletes a release or returns ErrReleaseNotFound. 136 func (mem *Memory) Delete(key string) (*rspb.Release, error) { 137 defer unlock(mem.wlock()) 138 139 switch elems := strings.Split(key, ".v"); len(elems) { 140 case 2: 141 name, ver := elems[0], elems[1] 142 if _, err := strconv.Atoi(ver); err != nil { 143 return nil, ErrInvalidKey 144 } 145 if recs, ok := mem.cache[name]; ok { 146 if r := recs.Remove(key); r != nil { 147 return r.rls, nil 148 } 149 } 150 return nil, ErrReleaseNotFound 151 default: 152 return nil, ErrInvalidKey 153 } 154 } 155 156 func (mem *Memory) dump(w io.Writer) error { 157 var b bytes.Buffer 158 159 fmt.Fprintln(&b, "memory:") 160 for key, recs := range mem.cache { 161 fmt.Fprintf(&b, "\t# %q\n", key) 162 163 recs.Iter(func(index int, r *record) bool { 164 fmt.Fprintf(&b, "\t\t- [%d] v%d (status = %s)\n", 165 index, 166 r.rls.Version, 167 r.rls.Info.Status.Code, 168 ) 169 170 return true 171 }) 172 } 173 174 _, err := w.Write(b.Bytes()) 175 return err 176 } 177 178 // wlock locks mem for writing 179 func (mem *Memory) wlock() func() { 180 mem.Lock() 181 return func() { mem.Unlock() } 182 } 183 184 // rlock locks mem for reading 185 func (mem *Memory) rlock() func() { 186 mem.RLock() 187 return func() { mem.RUnlock() } 188 } 189 190 // unlock calls fn which reverses a mem.rlock or mem.wlock. e.g: 191 // ```defer unlock(mem.rlock())```, locks mem for reading at the 192 // call point of defer and unlocks upon exiting the block. 193 func unlock(fn func()) { fn() }