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 }