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