github.com/influx6/npkg@v0.8.8/nstorage/nmap/mapexpr.go (about) 1 package nmap 2 3 import ( 4 regexp2 "regexp" 5 "time" 6 7 "github.com/influx6/npkg/nerror" 8 "github.com/influx6/npkg/nstorage" 9 ) 10 11 var _ nstorage.ExpirableStore = (*ExprByteStore)(nil) 12 13 // ExprByteStore implements an expiring byte store that 14 // matches the nstorage.ExpirableStorage interface. 15 type ExprByteStore struct { 16 cache *ExpiringByteMap 17 } 18 19 // NewExprByteStore returns a new instance of a ExprByteStore. 20 func NewExprByteStore(initial ...uint) *ExprByteStore { 21 var expr ExprByteStore 22 expr.cache = NewExpiringByteMap(initial...) 23 return &expr 24 } 25 26 func (expr *ExprByteStore) Count() (int64, error) { 27 return expr.cache.Count(), nil 28 } 29 30 // Keys returns the list of all keys registered to giving store. 31 func (expr *ExprByteStore) Keys() ([]string, error) { 32 var keys []string 33 expr.cache.GetMany(func(values map[string]ExpiringValue) { 34 keys = make([]string, 0, len(values)) 35 for key := range values { 36 keys = append(keys, key) 37 } 38 }) 39 return keys, nil 40 } 41 42 // GetAnyKeys returns the giving values of any key if it exists and has not expired. 43 func (expr *ExprByteStore) GetAnyKeys(k ...string) ([][]byte, error) { 44 return expr.cache.GetAnyKeys(k...) 45 } 46 47 // GetAllKeys returns the giving values of all keys. 48 func (expr *ExprByteStore) GetAllKeys(k ...string) ([][]byte, error) { 49 return expr.cache.GetAllKeys(k...) 50 } 51 52 // Get returns the giving value of key if it exists and has not expired. 53 func (expr *ExprByteStore) Get(k string) ([]byte, error) { 54 if !expr.cache.Has(k) { 55 return nil, nerror.New("not found") 56 } 57 return expr.cache.Get(k), nil 58 } 59 60 // TTL returns the remaining time left for giving key before expiration. 61 // 62 // A zero value means has no expiration. 63 func (expr *ExprByteStore) TTL(k string) (time.Duration, error) { 64 return expr.cache.TTL(k), nil 65 } 66 67 // Exists returns true/false if giving key exists. 68 func (expr *ExprByteStore) Exists(k string) (bool, error) { 69 return expr.cache.Has(k), nil 70 } 71 72 // Save adds giving key and value into store. 73 func (expr *ExprByteStore) Save(k string, v []byte) error { 74 var cm = append(make([]byte, 0, len(v)), v...) 75 expr.cache.Set(k, cm, 0) 76 return nil 77 } 78 79 // ExtendTTL extends expiration or sets expiration of giving key if it has not 80 // expired yet. 81 // 82 // A expiration value of zero means to persist the giving key. 83 func (expr *ExprByteStore) ExtendTTL(k string, t time.Duration) error { 84 expr.cache.ExtendTTL(k, t) 85 return nil 86 } 87 88 // ResetTTL resets expiration or sets expiration of giving key if it has not 89 // expired yet. 90 // 91 // A expiration value of zero means to persist the giving key. 92 func (expr *ExprByteStore) ResetTTL(k string, t time.Duration) error { 93 expr.cache.ResetTTL(k, t) 94 return nil 95 } 96 97 // Updates updates giving key and value into store. 98 func (expr *ExprByteStore) Update(k string, v []byte) error { 99 var cm = append(make([]byte, 0, len(v)), v...) 100 expr.cache.Set(k, cm, 0) 101 return nil 102 } 103 104 // SaveTTL updates giving key and value into store with expiration value. 105 func (expr *ExprByteStore) SaveTTL(k string, v []byte, t time.Duration) error { 106 var cm = append(make([]byte, 0, len(v)), v...) 107 expr.cache.Set(k, cm, t) 108 return nil 109 } 110 111 // UpdateTTL updates giving key and value into store with expiration value. 112 func (expr *ExprByteStore) UpdateTTL(k string, v []byte, t time.Duration) error { 113 if !expr.cache.Has(k) { 114 return nerror.New("key does not exists") 115 } 116 117 var cm = append(make([]byte, 0, len(v)), v...) 118 expr.cache.Set(k, cm, t) 119 return nil 120 } 121 122 // Each alternatives through all keys and values from underline cache. 123 // 124 // To ensure no-undesired behaviour, ensure to copy the value to avoid 125 // possible change to it, as the underline store owns the giving value 126 // slice and maybe re-used as it sees fit. 127 func (expr *ExprByteStore) Each(fn nstorage.EachItem) error { 128 var recvErr error 129 expr.cache.GetMany(func(values map[string]ExpiringValue) { 130 for key, value := range values { 131 if err := fn(value.Value, key); err != nil { 132 if nerror.IsAny(err, nstorage.ErrJustStop) { 133 return 134 } 135 recvErr = err 136 break 137 } 138 } 139 }) 140 if recvErr != nil { 141 return nerror.WrapOnly(recvErr) 142 } 143 return nil 144 } 145 146 // ScanMatch returns all elements matching giving function and count. 147 func (expr *ExprByteStore) ScanMatch(count int64, lastIndex int64, lastKey string, regexp string) (nstorage.ScanResult, error) { 148 var rs nstorage.ScanResult 149 150 var keys, keyFetchErr = expr.EachKeyMatch(regexp) 151 if keyFetchErr != nil { 152 return rs, nerror.WrapOnly(keyFetchErr) 153 } 154 155 var remainingKeys = keys[lastIndex : lastIndex+count] 156 157 rs.Keys = remainingKeys 158 rs.LastIndex = lastIndex + count 159 if int(rs.LastIndex) > len(keys) { 160 rs.LastIndex = int64(len(keys)) 161 rs.Finished = true 162 return rs, nil 163 } 164 165 rs.LastIndex = lastIndex + count 166 return rs, nil 167 } 168 169 // Find returns all elements matching giving function and count. 170 func (expr *ExprByteStore) EachKeyMatch(regexp string) ([]string, error) { 171 if len(regexp) == 0 { 172 regexp = ".+" 173 } 174 175 var generatedRegEx, rgErr = regexp2.Compile(regexp) 176 if rgErr != nil { 177 return nil, nerror.WrapOnly(rgErr) 178 } 179 180 var keys = make([]string, 0, 2) 181 expr.cache.GetMany(func(values map[string]ExpiringValue) { 182 for key := range values { 183 if !generatedRegEx.MatchString(key) { 184 continue 185 } 186 keys = append(keys, key) 187 } 188 }) 189 return keys, nil 190 } 191 192 // RemoveKeys deletes giving key from underling store. 193 func (expr *ExprByteStore) RemoveKeys(ks ...string) error { 194 expr.cache.GetMany(func(values map[string]ExpiringValue) { 195 for _, key := range ks { 196 delete(values, key) 197 } 198 }) 199 return nil 200 } 201 202 func (expr *ExprByteStore) Clear() { 203 expr.cache.Reset() 204 } 205 206 // Remove deletes giving key from underling store. 207 func (expr *ExprByteStore) Remove(k string) ([]byte, error) { 208 var v []byte 209 var found bool 210 expr.cache.GetMany(func(values map[string]ExpiringValue) { 211 var value, hasKey = values[k] 212 if !hasKey { 213 return 214 } 215 216 delete(values, k) 217 218 found = true 219 v = value.Value 220 }) 221 222 if !found { 223 return nil, nerror.New("Key does not exists") 224 } 225 return v, nil 226 }