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  }