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() }