gitlab.com/beacon-software/gadget@v0.0.0-20181217202115-54565ea1ed5e/storage/memory.go (about)

     1  package storage
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"gitlab.com/beacon-software/gadget/errors"
     7  )
     8  
     9  // ---------- Error Types ---------
    10  const (
    11  	// NoEntryForKey storage error msg
    12  	NoEntryForKey string = "no entry for key"
    13  )
    14  
    15  type memoryProvider struct {
    16  	shards map[string]Provider
    17  	values map[string]interface{}
    18  }
    19  
    20  // NewMemoryStorage for storing and retrieving key values.
    21  func NewMemoryStorage() Provider {
    22  	return &memoryProvider{values: make(map[string]interface{}), shards: make(map[string]Provider)}
    23  }
    24  
    25  // Shard returns a new instance of the storage provider with a seperate key space from this
    26  // storage provider. The shard should be accessible by calling this function with the same
    27  // shard name.
    28  func (mp *memoryProvider) Shard(name string) (Provider, error) {
    29  	shard, ok := mp.shards[name]
    30  	if !ok {
    31  		shard = NewMemoryStorage()
    32  		mp.shards[name] = shard
    33  	}
    34  	return shard, nil
    35  }
    36  
    37  func (mp *memoryProvider) Read(key string, target interface{}) error {
    38  	obj, ok := mp.values[key]
    39  	if !ok {
    40  		return errors.New(NoEntryForKey)
    41  	}
    42  	objValue := reflect.ValueOf(obj)
    43  	// We are putting the value in the pointer obj into the target
    44  	// 1. Get the value of target which is ptr/instance/slice to something we don't know about
    45  	targetValue := reflect.ValueOf(target)
    46  	if objValue.Kind() != targetValue.Kind() {
    47  		return errors.New("target (%d) and value (%d) are not of the same 'Kind'", targetValue.Kind(),
    48  			objValue.Kind())
    49  	}
    50  	// 2. Get the value of obj which is ptr/instance/slice of the unknown thing
    51  	// We could support Slice, Array, and Struct as well, but we don't need it right now.
    52  	switch objValue.Kind() {
    53  	case reflect.Interface:
    54  		// interface works the same as pointer
    55  		fallthrough
    56  	case reflect.Ptr:
    57  		// 3. Set the target value Elem to the objects Elem and we are done
    58  		targetValue.Elem().Set(objValue.Elem())
    59  	default:
    60  		return errors.New("reflect.Kind %d is not supported", objValue.Kind())
    61  	}
    62  	return nil
    63  }
    64  
    65  func (mp *memoryProvider) Write(key string, target interface{}) error {
    66  	mp.values[key] = target
    67  	return nil
    68  }
    69  
    70  func (mp *memoryProvider) Exists(key string) bool {
    71  	_, ok := mp.values[key]
    72  	return ok
    73  }
    74  
    75  func (mp *memoryProvider) Delete(key string) error {
    76  	delete(mp.values, key)
    77  	return nil
    78  }