github.com/m3db/m3@v1.5.0/src/cluster/kv/fake/store.go (about) 1 // Copyright (c) 2020 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package fake 22 23 import ( 24 "errors" 25 26 "github.com/m3db/m3/src/cluster/kv" 27 28 "github.com/golang/protobuf/proto" 29 ) 30 31 // NewStore returns a fakeStore adhering to the kv.Store interface. 32 // All methods except Watch are implemented. Implementation is not threadsafe 33 // and should only be used for tests. 34 func NewStore() kv.Store { 35 return &fakeStore{ 36 store: make(map[string][]kv.Value), 37 } 38 } 39 40 type fakeStore struct { 41 store map[string][]kv.Value 42 } 43 44 func (f *fakeStore) Get(key string) (kv.Value, error) { 45 value, ok := f.store[key] 46 if !ok { 47 return nil, kv.ErrNotFound 48 } 49 50 return value[len(value)-1], nil 51 } 52 53 func (f *fakeStore) Watch(_ string) (kv.ValueWatch, error) { 54 panic("implement me") 55 } 56 57 func (f *fakeStore) Set(key string, v proto.Message) (int, error) { 58 oldVal, err := f.Get(key) 59 if err != nil && err != kv.ErrNotFound { 60 return 0, err 61 } 62 63 data, err := proto.Marshal(v) 64 if err != nil { 65 return 0, err 66 } 67 68 var newVer int 69 if oldVal == nil { 70 f.store[key] = []kv.Value{newValue(data, int64(newVer))} 71 } else { 72 newVer = oldVal.Version() + 1 73 f.store[key] = append(f.store[key], newValue(data, int64(newVer))) 74 } 75 76 return newVer, nil 77 } 78 79 func (f *fakeStore) SetIfNotExists(key string, v proto.Message) (int, error) { 80 _, err := f.Get(key) 81 if err == kv.ErrNotFound { 82 return f.Set(key, v) 83 } else { 84 return 0, kv.ErrAlreadyExists 85 } 86 } 87 88 func (f *fakeStore) CheckAndSet(key string, version int, v proto.Message) (int, error) { 89 val, err := f.Get(key) 90 if err != nil && err != kv.ErrNotFound { 91 return 0, err 92 } else if err != nil && err == kv.ErrNotFound && version == 0 { 93 return f.Set(key, v) 94 } else if val == nil { 95 return 0, kv.ErrVersionMismatch 96 } else if val.Version() == version { 97 return f.Set(key, v) 98 } else { 99 return 0, kv.ErrVersionMismatch 100 } 101 } 102 103 func (f *fakeStore) Delete(key string) (kv.Value, error) { 104 val, err := f.Get(key) 105 if err != nil { 106 return nil, err 107 } 108 delete(f.store, key) 109 110 return val, nil 111 } 112 113 func (f *fakeStore) History(key string, from, to int) ([]kv.Value, error) { 114 if from > to || from < 0 || to < 0 { 115 return nil, errors.New("invalid history range") 116 } 117 118 if from == to { 119 return nil, nil 120 } 121 122 vals, ok := f.store[key] 123 if !ok { 124 return nil, kv.ErrNotFound 125 } 126 if to > len(vals) { 127 return nil, errors.New("invalid history range") 128 } 129 130 return vals[from:to], nil 131 } 132 133 type value struct { 134 Val []byte 135 Ver int64 136 } 137 138 func newValue(val []byte, ver int64) *value { 139 return &value{ 140 Val: val, 141 Ver: ver, 142 } 143 } 144 145 func (c *value) IsNewer(other kv.Value) bool { 146 return c.Version() > other.Version() 147 } 148 149 func (c *value) Unmarshal(v proto.Message) error { 150 err := proto.Unmarshal(c.Val, v) 151 return err 152 } 153 154 func (c *value) Version() int { 155 return int(c.Ver) 156 }