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 ©Kvp 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 }