github.com/amtisyAts/helm@v2.17.0+incompatible/pkg/storage/driver/memory.go (about) 1 /* 2 Copyright The Helm Authors. 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 "strconv" 21 "strings" 22 "sync" 23 24 rspb "k8s.io/helm/pkg/proto/hapi/release" 25 storageerrors "k8s.io/helm/pkg/storage/errors" 26 ) 27 28 var _ Driver = (*Memory)(nil) 29 30 // MemoryDriverName is the string name of this driver. 31 const MemoryDriverName = "Memory" 32 33 // Memory is the in-memory storage driver implementation. 34 type Memory struct { 35 sync.RWMutex 36 cache map[string]records 37 } 38 39 // NewMemory initializes a new memory driver. 40 func NewMemory() *Memory { 41 return &Memory{cache: map[string]records{}} 42 } 43 44 // Name returns the name of the driver. 45 func (mem *Memory) Name() string { 46 return MemoryDriverName 47 } 48 49 // Get returns the release named by key or returns ErrReleaseNotFound. 50 func (mem *Memory) Get(key string) (*rspb.Release, error) { 51 defer unlock(mem.rlock()) 52 53 switch elems := strings.Split(key, ".v"); len(elems) { 54 case 2: 55 name, ver := elems[0], elems[1] 56 if _, err := strconv.Atoi(ver); err != nil { 57 return nil, storageerrors.ErrInvalidKey(key) 58 } 59 if recs, ok := mem.cache[name]; ok { 60 if r := recs.Get(key); r != nil { 61 return r.rls, nil 62 } 63 } 64 return nil, storageerrors.ErrReleaseNotFound(key) 65 default: 66 return nil, storageerrors.ErrInvalidKey(key) 67 } 68 } 69 70 // List returns the list of all releases such that filter(release) == true 71 func (mem *Memory) List(filter func(*rspb.Release) bool) ([]*rspb.Release, error) { 72 defer unlock(mem.rlock()) 73 74 var ls []*rspb.Release 75 for _, recs := range mem.cache { 76 recs.Iter(func(_ int, rec *record) bool { 77 if filter(rec.rls) { 78 ls = append(ls, rec.rls) 79 } 80 return true 81 }) 82 } 83 return ls, nil 84 } 85 86 // Query returns the set of releases that match the provided set of labels 87 func (mem *Memory) Query(keyvals map[string]string) ([]*rspb.Release, error) { 88 defer unlock(mem.rlock()) 89 90 var lbs labels 91 92 lbs.init() 93 lbs.fromMap(keyvals) 94 95 var ls []*rspb.Release 96 for _, recs := range mem.cache { 97 recs.Iter(func(_ int, rec *record) bool { 98 // A query for a release name that doesn't exist (has been deleted) 99 // can cause rec to be nil. 100 if rec == nil { 101 return false 102 } 103 if rec.lbs.match(lbs) { 104 ls = append(ls, rec.rls) 105 } 106 return true 107 }) 108 } 109 return ls, nil 110 } 111 112 // Create creates a new release or returns ErrReleaseExists. 113 func (mem *Memory) Create(key string, rls *rspb.Release) error { 114 defer unlock(mem.wlock()) 115 116 if recs, ok := mem.cache[rls.Name]; ok { 117 if err := recs.Add(newRecord(key, rls)); err != nil { 118 return err 119 } 120 mem.cache[rls.Name] = recs 121 return nil 122 } 123 mem.cache[rls.Name] = records{newRecord(key, rls)} 124 return nil 125 } 126 127 // Update updates a release or returns ErrReleaseNotFound. 128 func (mem *Memory) Update(key string, rls *rspb.Release) error { 129 defer unlock(mem.wlock()) 130 131 if rs, ok := mem.cache[rls.Name]; ok && rs.Exists(key) { 132 rs.Replace(key, newRecord(key, rls)) 133 return nil 134 } 135 return storageerrors.ErrReleaseNotFound(rls.Name) 136 } 137 138 // Delete deletes a release or returns ErrReleaseNotFound. 139 func (mem *Memory) Delete(key string) (*rspb.Release, error) { 140 defer unlock(mem.wlock()) 141 142 elems := strings.Split(key, ".v") 143 144 if len(elems) != 2 { 145 return nil, storageerrors.ErrInvalidKey(key) 146 } 147 148 name, ver := elems[0], elems[1] 149 if _, err := strconv.Atoi(ver); err != nil { 150 return nil, storageerrors.ErrInvalidKey(key) 151 } 152 if recs, ok := mem.cache[name]; ok { 153 if r := recs.Remove(key); r != nil { 154 // recs.Remove changes the slice reference, so we have to re-assign it. 155 mem.cache[name] = recs 156 return r.rls, nil 157 } 158 } 159 return nil, storageerrors.ErrReleaseNotFound(key) 160 } 161 162 // wlock locks mem for writing 163 func (mem *Memory) wlock() func() { 164 mem.Lock() 165 return func() { mem.Unlock() } 166 } 167 168 // rlock locks mem for reading 169 func (mem *Memory) rlock() func() { 170 mem.RLock() 171 return func() { mem.RUnlock() } 172 } 173 174 // unlock calls fn which reverses a mem.rlock or mem.wlock. e.g: 175 // ```defer unlock(mem.rlock())```, locks mem for reading at the 176 // call point of defer and unlocks upon exiting the block. 177 func unlock(fn func()) { fn() }