github.com/portworx/kvdb@v0.0.0-20241107215734-a185a966f535/mem/kv_mem.go (about)

     1  package mem
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"strings"
     9  	"sync"
    10  	"sync/atomic"
    11  	"time"
    12  
    13  	"github.com/portworx/kvdb"
    14  	"github.com/portworx/kvdb/common"
    15  	"github.com/sirupsen/logrus"
    16  )
    17  
    18  const (
    19  	// Name is the name of this kvdb implementation.
    20  	Name = "kv-mem"
    21  	// KvSnap is an option passed to designate this kvdb as a snap.
    22  	KvSnap = "KvSnap"
    23  	// KvUseInterface is an option passed that configures the mem to store
    24  	// the values as interfaces instead of bytes. It will not create a
    25  	// copy of the interface that is passed in. USE WITH CAUTION
    26  	KvUseInterface = "KvUseInterface"
    27  	bootstrapKey   = "bootstrap"
    28  )
    29  
    30  var (
    31  	// ErrSnap is returned if an operation is not supported on a snap.
    32  	ErrSnap = errors.New("operation not supported on snap")
    33  	// ErrSnapWithInterfaceNotSupported is returned when a snap kv-mem is
    34  	// created with KvUseInterface flag on
    35  	ErrSnapWithInterfaceNotSupported = errors.New("snap kvdb not supported with interfaces")
    36  	// ErrIllegalSelect is returned when an incorrect select function
    37  	// implementation is detected.
    38  	ErrIllegalSelect = errors.New("Illegal Select implementation")
    39  )
    40  
    41  func init() {
    42  	if err := kvdb.Register(Name, New, Version); err != nil {
    43  		panic(err.Error())
    44  	}
    45  }
    46  
    47  type memKV struct {
    48  	common.BaseKvdb
    49  	// m is the key value database
    50  	m map[string]*memKVPair
    51  	// updates is the list of latest few updates
    52  	dist WatchDistributor
    53  	// mutex protects m, w, wt
    54  	mutex sync.Mutex
    55  	// index current kvdb index
    56  	index  uint64
    57  	domain string
    58  	// locks is the map of currently held locks
    59  	locks map[string]chan int
    60  	// noByte will store all the values as interface
    61  	noByte bool
    62  	kvdb.Controller
    63  }
    64  
    65  type memKVPair struct {
    66  	kvdb.KVPair
    67  	// ivalue is the value for this kv pair stored as an interface
    68  	ivalue interface{}
    69  }
    70  
    71  func (mkvp *memKVPair) copy() *kvdb.KVPair {
    72  	copyKvp := mkvp.KVPair
    73  	if mkvp.Value == nil && mkvp.ivalue != nil {
    74  		copyKvp.Value, _ = common.ToBytes(mkvp.ivalue)
    75  	}
    76  	return &copyKvp
    77  }
    78  
    79  type snapMem struct {
    80  	*memKV
    81  }
    82  
    83  // watchUpdate refers to an update to this kvdb
    84  type watchUpdate struct {
    85  	// key is the key that was updated
    86  	key string
    87  	// kvp is the key-value that was updated
    88  	kvp memKVPair
    89  	// err is any error on update
    90  	err error
    91  }
    92  
    93  // WatchUpdateQueue is a producer consumer queue.
    94  type WatchUpdateQueue interface {
    95  	// Enqueue will enqueue an update. It is non-blocking.
    96  	Enqueue(update *watchUpdate)
    97  	// Dequeue will either return an element from front of the queue or
    98  	// will block until element becomes available
    99  	Dequeue() *watchUpdate
   100  }
   101  
   102  // WatchDistributor distributes updates to the watchers
   103  type WatchDistributor interface {
   104  	// Add creates a new watch queue to send updates
   105  	Add() WatchUpdateQueue
   106  	// Remove removes an existing watch queue
   107  	Remove(WatchUpdateQueue)
   108  	// NewUpdate is invoked to distribute a new update
   109  	NewUpdate(w *watchUpdate)
   110  }
   111  
   112  // distributor implements WatchDistributor interface
   113  type distributor struct {
   114  	sync.Mutex
   115  	// updates is the list of latest few updates
   116  	updates []*watchUpdate
   117  	// watchers watch for updates
   118  	watchers []WatchUpdateQueue
   119  }
   120  
   121  // NewWatchDistributor returns a new instance of
   122  // the WatchDistrubtor interface
   123  func NewWatchDistributor() WatchDistributor {
   124  	return &distributor{}
   125  }
   126  
   127  func (d *distributor) Add() WatchUpdateQueue {
   128  	d.Lock()
   129  	defer d.Unlock()
   130  	q := NewWatchUpdateQueue()
   131  	for _, u := range d.updates {
   132  		q.Enqueue(u)
   133  	}
   134  	d.watchers = append(d.watchers, q)
   135  	return q
   136  }
   137  
   138  func (d *distributor) Remove(r WatchUpdateQueue) {
   139  	d.Lock()
   140  	defer d.Unlock()
   141  	for i, q := range d.watchers {
   142  		if q == r {
   143  			copy(d.watchers[i:], d.watchers[i+1:])
   144  			d.watchers[len(d.watchers)-1] = nil
   145  			d.watchers = d.watchers[:len(d.watchers)-1]
   146  		}
   147  	}
   148  }
   149  
   150  func (d *distributor) NewUpdate(u *watchUpdate) {
   151  	d.Lock()
   152  	defer d.Unlock()
   153  	// collect update
   154  	d.updates = append(d.updates, u)
   155  	if len(d.updates) > 100 {
   156  		d.updates = d.updates[100:]
   157  	}
   158  	// send update to watchers
   159  	for _, q := range d.watchers {
   160  		q.Enqueue(u)
   161  	}
   162  }
   163  
   164  // watchQueue implements WatchUpdateQueue interface for watchUpdates
   165  type watchQueue struct {
   166  	// updates is the list of updates
   167  	updates []*watchUpdate
   168  	// m is the mutex to protect updates
   169  	m *sync.Mutex
   170  	// cv is used to coordinate the producer-consumer threads
   171  	cv *sync.Cond
   172  }
   173  
   174  // NewWatchUpdateQueue returns an instance of WatchUpdateQueue
   175  func NewWatchUpdateQueue() WatchUpdateQueue {
   176  	mtx := &sync.Mutex{}
   177  	return &watchQueue{
   178  		m:       mtx,
   179  		cv:      sync.NewCond(mtx),
   180  		updates: make([]*watchUpdate, 0)}
   181  }
   182  
   183  func (w *watchQueue) Dequeue() *watchUpdate {
   184  	w.m.Lock()
   185  	for {
   186  		if len(w.updates) > 0 {
   187  			update := w.updates[0]
   188  			w.updates = w.updates[1:]
   189  			w.m.Unlock()
   190  			return update
   191  		}
   192  		w.cv.Wait()
   193  	}
   194  }
   195  
   196  // Enqueue enqueues and never blocks
   197  func (w *watchQueue) Enqueue(update *watchUpdate) {
   198  	w.m.Lock()
   199  	w.updates = append(w.updates, update)
   200  	w.cv.Signal()
   201  	w.m.Unlock()
   202  }
   203  
   204  type watchData struct {
   205  	cb        kvdb.WatchCB
   206  	opaque    interface{}
   207  	waitIndex uint64
   208  }
   209  
   210  // New constructs a new kvdb.Kvdb.
   211  func New(
   212  	domain string,
   213  	machines []string,
   214  	options map[string]string,
   215  	fatalErrorCb kvdb.FatalErrorCB,
   216  ) (kvdb.Kvdb, error) {
   217  	if domain != "" && !strings.HasSuffix(domain, "/") {
   218  		domain = domain + "/"
   219  	}
   220  
   221  	mem := &memKV{
   222  		BaseKvdb:   common.BaseKvdb{FatalCb: fatalErrorCb, LockTryDuration: kvdb.DefaultLockTryDuration},
   223  		m:          make(map[string]*memKVPair),
   224  		dist:       NewWatchDistributor(),
   225  		domain:     domain,
   226  		Controller: kvdb.ControllerNotSupported,
   227  		locks:      make(map[string]chan int),
   228  	}
   229  
   230  	var noByte bool
   231  	if _, noByte = options[KvUseInterface]; noByte {
   232  		mem.noByte = true
   233  	}
   234  	if _, ok := options[KvSnap]; ok && !noByte {
   235  		return &snapMem{memKV: mem}, nil
   236  	} else if ok && noByte {
   237  		return nil, ErrSnapWithInterfaceNotSupported
   238  	}
   239  	return mem, nil
   240  }
   241  
   242  // Version returns the supported version of the mem implementation
   243  func Version(url string, kvdbOptions map[string]string) (string, error) {
   244  	return kvdb.MemVersion1, nil
   245  }
   246  
   247  func (kv *memKV) String() string {
   248  	return Name
   249  }
   250  
   251  func (kv *memKV) Capabilities() int {
   252  	return kvdb.KVCapabilityOrderedUpdates
   253  }
   254  
   255  func (kv *memKV) get(key string) (*memKVPair, error) {
   256  	key = kv.domain + key
   257  	v, ok := kv.m[key]
   258  	if !ok {
   259  		return nil, kvdb.ErrNotFound
   260  	}
   261  	return v, nil
   262  }
   263  
   264  func (kv *memKV) exists(key string) (*memKVPair, error) {
   265  	return kv.get(key)
   266  }
   267  
   268  func (kv *memKV) Get(key string) (*kvdb.KVPair, error) {
   269  	kv.mutex.Lock()
   270  	defer kv.mutex.Unlock()
   271  	v, err := kv.get(key)
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  	return v.copy(), nil
   276  }
   277  
   278  func (kv *memKV) Snapshot(prefixes []string, consistent bool) (kvdb.Kvdb, uint64, error) {
   279  	kv.mutex.Lock()
   280  	defer kv.mutex.Unlock()
   281  	_, err := kv.put(bootstrapKey, time.Now().UnixNano(), 0)
   282  	if err != nil {
   283  		return nil, 0, fmt.Errorf("Failed to create snap bootstrap key: %v", err)
   284  	}
   285  	data := make(map[string]*memKVPair)
   286  	for key, value := range kv.m {
   287  		if strings.Contains(key, "/_") {
   288  			continue
   289  		}
   290  		found := false
   291  		for _, prefix := range prefixes {
   292  			prefix = kv.domain + prefix
   293  			if strings.HasPrefix(key, prefix) {
   294  				found = true
   295  				break
   296  			}
   297  		}
   298  		if !found {
   299  			continue
   300  		}
   301  		snap := &memKVPair{}
   302  		snap.KVPair = value.KVPair
   303  		cpy := value.copy()
   304  		snap.Value = make([]byte, len(cpy.Value))
   305  		copy(snap.Value, cpy.Value)
   306  		data[key] = snap
   307  	}
   308  	highestKvPair, _ := kv.delete(bootstrapKey)
   309  	// Snapshot only data, watches are not copied.
   310  	return &snapMem{
   311  		&memKV{
   312  			m:      data,
   313  			domain: kv.domain,
   314  		},
   315  	}, highestKvPair.ModifiedIndex, nil
   316  }
   317  
   318  func (kv *memKV) put(
   319  	key string,
   320  	value interface{},
   321  	ttl uint64,
   322  ) (*kvdb.KVPair, error) {
   323  
   324  	var (
   325  		kvp  *memKVPair
   326  		b    []byte
   327  		err  error
   328  		ival interface{}
   329  	)
   330  
   331  	suffix := key
   332  	key = kv.domain + suffix
   333  	index := atomic.AddUint64(&kv.index, 1)
   334  
   335  	// Either set bytes or interface value
   336  	if !kv.noByte {
   337  		b, err = common.ToBytes(value)
   338  		if err != nil {
   339  			return nil, err
   340  		}
   341  	} else {
   342  		ival = value
   343  	}
   344  	if old, ok := kv.m[key]; ok {
   345  		old.Value = b
   346  		old.ivalue = ival
   347  		old.Action = kvdb.KVSet
   348  		old.ModifiedIndex = index
   349  		old.KVDBIndex = index
   350  		kvp = old
   351  	} else {
   352  		kvp = &memKVPair{
   353  			KVPair: kvdb.KVPair{
   354  				Key:           key,
   355  				Value:         b,
   356  				TTL:           int64(ttl),
   357  				KVDBIndex:     index,
   358  				ModifiedIndex: index,
   359  				CreatedIndex:  index,
   360  				Action:        kvdb.KVCreate,
   361  			},
   362  			ivalue: ival,
   363  		}
   364  		kv.m[key] = kvp
   365  	}
   366  
   367  	kv.normalize(&kvp.KVPair)
   368  	kv.dist.NewUpdate(&watchUpdate{key, *kvp, nil})
   369  
   370  	if ttl != 0 {
   371  		time.AfterFunc(time.Second*time.Duration(ttl), func() {
   372  			// TODO: handle error
   373  			kv.mutex.Lock()
   374  			defer kv.mutex.Unlock()
   375  			_, _ = kv.delete(suffix)
   376  		})
   377  	}
   378  
   379  	return kvp.copy(), nil
   380  }
   381  
   382  func (kv *memKV) Put(
   383  	key string,
   384  	value interface{},
   385  	ttl uint64,
   386  ) (*kvdb.KVPair, error) {
   387  
   388  	kv.mutex.Lock()
   389  	defer kv.mutex.Unlock()
   390  	return kv.put(key, value, ttl)
   391  }
   392  
   393  func (kv *memKV) GetVal(key string, v interface{}) (*kvdb.KVPair, error) {
   394  	kv.mutex.Lock()
   395  	defer kv.mutex.Unlock()
   396  	kvp, err := kv.get(key)
   397  	if err != nil {
   398  		return nil, err
   399  	}
   400  
   401  	cpy := kvp.copy()
   402  	err = json.Unmarshal(cpy.Value, v)
   403  	return cpy, err
   404  }
   405  
   406  func (kv *memKV) Create(
   407  	key string,
   408  	value interface{},
   409  	ttl uint64,
   410  ) (*kvdb.KVPair, error) {
   411  	kv.mutex.Lock()
   412  	defer kv.mutex.Unlock()
   413  
   414  	result, err := kv.exists(key)
   415  	if err != nil {
   416  		return kv.put(key, value, ttl)
   417  	}
   418  	return &result.KVPair, kvdb.ErrExist
   419  }
   420  
   421  func (kv *memKV) Update(
   422  	key string,
   423  	value interface{},
   424  	ttl uint64,
   425  ) (*kvdb.KVPair, error) {
   426  	kv.mutex.Lock()
   427  	defer kv.mutex.Unlock()
   428  
   429  	if _, err := kv.exists(key); err != nil {
   430  		return nil, kvdb.ErrNotFound
   431  	}
   432  	return kv.put(key, value, ttl)
   433  }
   434  
   435  func (kv *memKV) Enumerate(prefix string) (kvdb.KVPairs, error) {
   436  	kv.mutex.Lock()
   437  	defer kv.mutex.Unlock()
   438  	return kv.enumerate(prefix)
   439  }
   440  
   441  // enumerate returns a list of values and creates a copy if specified
   442  func (kv *memKV) enumerate(prefix string) (kvdb.KVPairs, error) {
   443  	var kvp = make(kvdb.KVPairs, 0, 100)
   444  	prefix = kv.domain + prefix
   445  
   446  	for k, v := range kv.m {
   447  		if strings.HasPrefix(k, prefix) && !strings.Contains(k, "/_") {
   448  			kvpLocal := v.copy()
   449  			kvpLocal.Key = k
   450  			kv.normalize(kvpLocal)
   451  			kvp = append(kvp, kvpLocal)
   452  		}
   453  	}
   454  
   455  	return kvp, nil
   456  }
   457  
   458  func (kv *memKV) delete(key string) (*kvdb.KVPair, error) {
   459  	kvp, err := kv.get(key)
   460  	if err != nil {
   461  		return nil, err
   462  	}
   463  	kvp.KVDBIndex = atomic.AddUint64(&kv.index, 1)
   464  	kvp.ModifiedIndex = kvp.KVDBIndex
   465  	kvp.Action = kvdb.KVDelete
   466  	delete(kv.m, kv.domain+key)
   467  	kv.dist.NewUpdate(&watchUpdate{kv.domain + key, *kvp, nil})
   468  	return &kvp.KVPair, nil
   469  }
   470  
   471  func (kv *memKV) Delete(key string) (*kvdb.KVPair, error) {
   472  	kv.mutex.Lock()
   473  	defer kv.mutex.Unlock()
   474  
   475  	return kv.delete(key)
   476  }
   477  
   478  func (kv *memKV) DeleteTree(prefix string) error {
   479  	kv.mutex.Lock()
   480  	defer kv.mutex.Unlock()
   481  
   482  	if len(prefix) > 0 && !strings.HasSuffix(prefix, kvdb.DefaultSeparator) {
   483  		prefix += kvdb.DefaultSeparator
   484  	}
   485  
   486  	kvp, err := kv.enumerate(prefix)
   487  	if err != nil {
   488  		return err
   489  	}
   490  	for _, v := range kvp {
   491  		// TODO: multiple errors
   492  		if _, iErr := kv.delete(v.Key); iErr != nil {
   493  			err = iErr
   494  		}
   495  	}
   496  	return err
   497  }
   498  
   499  func (kv *memKV) Keys(prefix, sep string) ([]string, error) {
   500  	if "" == sep {
   501  		sep = "/"
   502  	}
   503  	prefix = kv.domain + prefix
   504  	lenPrefix := len(prefix)
   505  	lenSep := len(sep)
   506  	if prefix[lenPrefix-lenSep:] != sep {
   507  		prefix += sep
   508  		lenPrefix += lenSep
   509  	}
   510  	seen := make(map[string]bool)
   511  	kv.mutex.Lock()
   512  	defer kv.mutex.Unlock()
   513  
   514  	for k := range kv.m {
   515  		if strings.HasPrefix(k, prefix) && !strings.Contains(k, "/_") {
   516  			key := k[lenPrefix:]
   517  			if idx := strings.Index(key, sep); idx > 0 {
   518  				key = key[:idx]
   519  			}
   520  			seen[key] = true
   521  		}
   522  	}
   523  	retList := make([]string, len(seen))
   524  	i := 0
   525  	for k := range seen {
   526  		retList[i] = k
   527  		i++
   528  	}
   529  
   530  	return retList, nil
   531  }
   532  
   533  func (kv *memKV) CompareAndSet(
   534  	kvp *kvdb.KVPair,
   535  	flags kvdb.KVFlags,
   536  	prevValue []byte,
   537  ) (*kvdb.KVPair, error) {
   538  
   539  	kv.mutex.Lock()
   540  	defer kv.mutex.Unlock()
   541  
   542  	result, err := kv.exists(kvp.Key)
   543  	if err != nil {
   544  		return nil, err
   545  	}
   546  	if prevValue != nil {
   547  		cpy := result.copy()
   548  		if !bytes.Equal(cpy.Value, prevValue) {
   549  			return nil, kvdb.ErrValueMismatch
   550  		}
   551  	}
   552  	if flags == kvdb.KVModifiedIndex {
   553  		if kvp.ModifiedIndex != result.ModifiedIndex {
   554  			return nil, kvdb.ErrValueMismatch
   555  		}
   556  	}
   557  	return kv.put(kvp.Key, kvp.Value, 0)
   558  }
   559  
   560  func (kv *memKV) CompareAndDelete(
   561  	kvp *kvdb.KVPair,
   562  	flags kvdb.KVFlags,
   563  ) (*kvdb.KVPair, error) {
   564  	kv.mutex.Lock()
   565  	defer kv.mutex.Unlock()
   566  
   567  	result, err := kv.exists(kvp.Key)
   568  	if err != nil {
   569  		return nil, err
   570  	}
   571  
   572  	if flags&kvdb.KVModifiedIndex > 0 && result.ModifiedIndex != kvp.ModifiedIndex {
   573  		return nil, kvdb.ErrModified
   574  	} else {
   575  		cpy := result.copy()
   576  		if !bytes.Equal(cpy.Value, kvp.Value) {
   577  			return nil, kvdb.ErrNotFound
   578  		}
   579  	}
   580  
   581  	return kv.delete(kvp.Key)
   582  }
   583  
   584  func (kv *memKV) WatchKey(
   585  	key string,
   586  	waitIndex uint64,
   587  	opaque interface{},
   588  	cb kvdb.WatchCB,
   589  ) error {
   590  	kv.mutex.Lock()
   591  	defer kv.mutex.Unlock()
   592  	key = kv.domain + key
   593  	go kv.watchCb(kv.dist.Add(), key,
   594  		&watchData{cb: cb, waitIndex: waitIndex, opaque: opaque},
   595  		false)
   596  	return nil
   597  }
   598  
   599  func (kv *memKV) WatchTree(
   600  	prefix string,
   601  	waitIndex uint64,
   602  	opaque interface{},
   603  	cb kvdb.WatchCB,
   604  ) error {
   605  	kv.mutex.Lock()
   606  	defer kv.mutex.Unlock()
   607  	prefix = kv.domain + prefix
   608  	go kv.watchCb(kv.dist.Add(), prefix,
   609  		&watchData{cb: cb, waitIndex: waitIndex, opaque: opaque},
   610  		true)
   611  	return nil
   612  }
   613  
   614  func (kv *memKV) Compact(
   615  	index uint64,
   616  ) error {
   617  	return kvdb.ErrNotSupported
   618  }
   619  
   620  func (kv *memKV) Lock(key string) (*kvdb.KVPair, error) {
   621  	return kv.LockWithID(key, "locked")
   622  }
   623  
   624  func (kv *memKV) LockWithID(
   625  	key string,
   626  	lockerID string,
   627  ) (*kvdb.KVPair, error) {
   628  	return kv.LockWithTimeout(key, lockerID, kv.LockTryDuration, kv.GetLockHoldDuration())
   629  }
   630  
   631  func (kv *memKV) IsKeyLocked(key string) (bool, string, error) {
   632  	key = kv.domain + key
   633  
   634  	// First check if such a key exists
   635  	var lockerID string
   636  	value, err := kv.Get(key)
   637  	if err == kvdb.ErrNotFound {
   638  		return false, "", nil
   639  	} else if err != nil {
   640  		return false, "", err
   641  	}
   642  	lockerID = string(value.Value)
   643  
   644  	// If a key exists, next check if it's a valid lock
   645  	kv.mutex.Lock()
   646  	if _, ok := kv.locks[key]; !ok {
   647  		kv.mutex.Unlock()
   648  		return false, "", kvdb.ErrInvalidLock
   649  	}
   650  	kv.mutex.Unlock()
   651  	return true, lockerID, nil
   652  }
   653  
   654  func (kv *memKV) LockWithTimeout(
   655  	key string,
   656  	lockerID string,
   657  	lockTryDuration time.Duration,
   658  	lockHoldDuration time.Duration,
   659  ) (*kvdb.KVPair, error) {
   660  	key = kv.domain + key
   661  	duration := time.Second
   662  
   663  	result, err := kv.Create(key, lockerID, uint64(duration*3))
   664  	startTime := time.Now()
   665  	for count := 0; err != nil; count++ {
   666  		time.Sleep(duration)
   667  		result, err = kv.Create(key, lockerID, uint64(duration*3))
   668  		if err != nil && count > 0 && count%15 == 0 {
   669  			var currLockerID string
   670  			if _, errGet := kv.GetVal(key, currLockerID); errGet == nil {
   671  				logrus.Infof("Lock %v locked for %v seconds, tag: %v",
   672  					key, count, currLockerID)
   673  			}
   674  		}
   675  		if err != nil && time.Since(startTime) > lockTryDuration {
   676  			return nil, err
   677  		}
   678  	}
   679  
   680  	if err != nil {
   681  		return nil, err
   682  	}
   683  
   684  	lockChan := make(chan int)
   685  	kv.mutex.Lock()
   686  	kv.locks[key] = lockChan
   687  	kv.mutex.Unlock()
   688  	if lockHoldDuration > 0 {
   689  		go func() {
   690  			timeout := time.After(lockHoldDuration)
   691  			for {
   692  				select {
   693  				case <-timeout:
   694  					kv.LockTimedout(key, lockHoldDuration)
   695  				case <-lockChan:
   696  					return
   697  				}
   698  			}
   699  		}()
   700  	}
   701  
   702  	return result, err
   703  }
   704  
   705  func (kv *memKV) Unlock(kvp *kvdb.KVPair) error {
   706  	kv.mutex.Lock()
   707  	lockChan, ok := kv.locks[kvp.Key]
   708  	if ok {
   709  		delete(kv.locks, kvp.Key)
   710  	}
   711  	kv.mutex.Unlock()
   712  	if lockChan != nil {
   713  		close(lockChan)
   714  	}
   715  	_, err := kv.CompareAndDelete(kvp, kvdb.KVFlags(0))
   716  	return err
   717  }
   718  
   719  func (kv *memKV) EnumerateWithSelect(
   720  	prefix string,
   721  	enumerateSelect kvdb.EnumerateSelect,
   722  	copySelect kvdb.CopySelect,
   723  ) ([]interface{}, error) {
   724  	if enumerateSelect == nil || copySelect == nil {
   725  		return nil, ErrIllegalSelect
   726  	}
   727  	kv.mutex.Lock()
   728  	defer kv.mutex.Unlock()
   729  	var kvi []interface{}
   730  	prefix = kv.domain + prefix
   731  	for k, v := range kv.m {
   732  		if strings.HasPrefix(k, prefix) && !strings.Contains(k, "/_") {
   733  			if enumerateSelect(v.ivalue) {
   734  				cpy := copySelect(v.ivalue)
   735  				if cpy == nil {
   736  					return nil, ErrIllegalSelect
   737  				}
   738  				kvi = append(kvi, cpy)
   739  			}
   740  		}
   741  	}
   742  	return kvi, nil
   743  }
   744  
   745  func (kv *memKV) EnumerateKVPWithSelect(
   746  	prefix string,
   747  	enumerateSelect kvdb.EnumerateKVPSelect,
   748  	copySelect kvdb.CopyKVPSelect,
   749  ) (kvdb.KVPairs, error) {
   750  	if enumerateSelect == nil || copySelect == nil {
   751  		return nil, ErrIllegalSelect
   752  	}
   753  	kv.mutex.Lock()
   754  	defer kv.mutex.Unlock()
   755  	var kvi kvdb.KVPairs
   756  	prefix = kv.domain + prefix
   757  	for k, v := range kv.m {
   758  		if strings.HasPrefix(k, prefix) && !strings.Contains(k, "/_") {
   759  			if enumerateSelect(&v.KVPair, v.ivalue) {
   760  				cpy := copySelect(&v.KVPair, v.ivalue)
   761  				if cpy == nil {
   762  					return nil, ErrIllegalSelect
   763  				}
   764  				kvi = append(kvi, cpy)
   765  			}
   766  		}
   767  	}
   768  	return kvi, nil
   769  }
   770  
   771  func (kv *memKV) GetWithCopy(
   772  	key string,
   773  	copySelect kvdb.CopySelect,
   774  ) (interface{}, error) {
   775  	if copySelect == nil {
   776  		return nil, ErrIllegalSelect
   777  	}
   778  	kv.mutex.Lock()
   779  	defer kv.mutex.Unlock()
   780  	kvp, err := kv.get(key)
   781  	if err != nil {
   782  		return nil, err
   783  	}
   784  	return copySelect(kvp.ivalue), nil
   785  }
   786  
   787  func (kv *memKV) TxNew() (kvdb.Tx, error) {
   788  	return nil, kvdb.ErrNotSupported
   789  }
   790  
   791  func (kv *memKV) normalize(kvp *kvdb.KVPair) {
   792  	kvp.Key = strings.TrimPrefix(kvp.Key, kv.domain)
   793  }
   794  
   795  func copyWatchKeys(w map[string]*watchData) []string {
   796  	keys := make([]string, len(w))
   797  	i := 0
   798  	for key := range w {
   799  		keys[i] = key
   800  		i++
   801  	}
   802  	return keys
   803  }
   804  
   805  func (kv *memKV) watchCb(
   806  	q WatchUpdateQueue,
   807  	prefix string,
   808  	v *watchData,
   809  	treeWatch bool,
   810  ) {
   811  	for {
   812  		update := q.Dequeue()
   813  		if ((treeWatch && strings.HasPrefix(update.key, prefix)) ||
   814  			(!treeWatch && update.key == prefix)) &&
   815  			(v.waitIndex == 0 || v.waitIndex < update.kvp.ModifiedIndex) {
   816  			kvpCopy := update.kvp.copy()
   817  			err := v.cb(update.key, v.opaque, kvpCopy, update.err)
   818  			if err != nil {
   819  				_ = v.cb("", v.opaque, nil, kvdb.ErrWatchStopped)
   820  				kv.dist.Remove(q)
   821  				return
   822  			}
   823  		}
   824  	}
   825  }
   826  
   827  func (kv *memKV) SnapPut(snapKvp *kvdb.KVPair) (*kvdb.KVPair, error) {
   828  	return nil, kvdb.ErrNotSupported
   829  }
   830  
   831  func (kv *snapMem) SnapPut(snapKvp *kvdb.KVPair) (*kvdb.KVPair, error) {
   832  	var kvp *memKVPair
   833  
   834  	key := kv.domain + snapKvp.Key
   835  	kv.mutex.Lock()
   836  	defer kv.mutex.Unlock()
   837  
   838  	if old, ok := kv.m[key]; ok {
   839  		old.Value = snapKvp.Value
   840  		old.Action = kvdb.KVSet
   841  		old.ModifiedIndex = snapKvp.ModifiedIndex
   842  		old.KVDBIndex = snapKvp.KVDBIndex
   843  		kvp = old
   844  
   845  	} else {
   846  		kvp = &memKVPair{
   847  			KVPair: kvdb.KVPair{
   848  				Key:           key,
   849  				Value:         snapKvp.Value,
   850  				TTL:           0,
   851  				KVDBIndex:     snapKvp.KVDBIndex,
   852  				ModifiedIndex: snapKvp.ModifiedIndex,
   853  				CreatedIndex:  snapKvp.CreatedIndex,
   854  				Action:        kvdb.KVCreate,
   855  			},
   856  		}
   857  		kv.m[key] = kvp
   858  	}
   859  
   860  	kv.normalize(&kvp.KVPair)
   861  	return &kvp.KVPair, nil
   862  }
   863  
   864  func (kv *snapMem) Put(
   865  	key string,
   866  	value interface{},
   867  	ttl uint64,
   868  ) (*kvdb.KVPair, error) {
   869  	return nil, ErrSnap
   870  }
   871  
   872  func (kv *snapMem) Create(
   873  	key string,
   874  	value interface{},
   875  	ttl uint64,
   876  ) (*kvdb.KVPair, error) {
   877  	return nil, ErrSnap
   878  }
   879  
   880  func (kv *snapMem) Update(
   881  	key string,
   882  	value interface{},
   883  	ttl uint64,
   884  ) (*kvdb.KVPair, error) {
   885  	return nil, ErrSnap
   886  }
   887  
   888  func (kv *snapMem) Delete(snapKey string) (*kvdb.KVPair, error) {
   889  	key := kv.domain + snapKey
   890  	kv.mutex.Lock()
   891  	defer kv.mutex.Unlock()
   892  	kvp, ok := kv.m[key]
   893  	if !ok {
   894  		return nil, kvdb.ErrNotFound
   895  	}
   896  	kvPair := kvp.KVPair
   897  	delete(kv.m, key)
   898  	return &kvPair, nil
   899  }
   900  
   901  func (kv *snapMem) DeleteTree(prefix string) error {
   902  	return ErrSnap
   903  }
   904  
   905  func (kv *snapMem) CompareAndSet(
   906  	kvp *kvdb.KVPair,
   907  	flags kvdb.KVFlags,
   908  	prevValue []byte,
   909  ) (*kvdb.KVPair, error) {
   910  	return nil, ErrSnap
   911  }
   912  
   913  func (kv *snapMem) CompareAndDelete(
   914  	kvp *kvdb.KVPair,
   915  	flags kvdb.KVFlags,
   916  ) (*kvdb.KVPair, error) {
   917  	return nil, ErrSnap
   918  }
   919  
   920  func (kv *snapMem) WatchKey(
   921  	key string,
   922  	waitIndex uint64,
   923  	opaque interface{},
   924  	watchCB kvdb.WatchCB,
   925  ) error {
   926  	return ErrSnap
   927  }
   928  
   929  func (kv *snapMem) WatchTree(
   930  	prefix string,
   931  	waitIndex uint64,
   932  	opaque interface{},
   933  	watchCB kvdb.WatchCB,
   934  ) error {
   935  	return ErrSnap
   936  }
   937  
   938  func (kv *memKV) AddUser(username string, password string) error {
   939  	return kvdb.ErrNotSupported
   940  }
   941  
   942  func (kv *memKV) RemoveUser(username string) error {
   943  	return kvdb.ErrNotSupported
   944  }
   945  
   946  func (kv *memKV) GrantUserAccess(
   947  	username string,
   948  	permType kvdb.PermissionType,
   949  	subtree string,
   950  ) error {
   951  	return kvdb.ErrNotSupported
   952  }
   953  
   954  func (kv *memKV) RevokeUsersAccess(
   955  	username string,
   956  	permType kvdb.PermissionType,
   957  	subtree string,
   958  ) error {
   959  	return kvdb.ErrNotSupported
   960  }
   961  
   962  func (kv *memKV) Serialize() ([]byte, error) {
   963  
   964  	kvps, err := kv.Enumerate("")
   965  	if err != nil {
   966  		return nil, err
   967  	}
   968  	return kv.SerializeAll(kvps)
   969  }
   970  
   971  func (kv *memKV) Deserialize(b []byte) (kvdb.KVPairs, error) {
   972  	return kv.DeserializeAll(b)
   973  }