github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/allegrosql/memdb_snapshot.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ekv 15 16 import "context" 17 18 func (EDB *memdb) SnapshotGetter() Getter { 19 return &memdbSnapGetter{ 20 EDB: EDB, 21 cp: EDB.getSnapshot(), 22 } 23 } 24 25 func (EDB *memdb) SnapshotIter(start, end Key) Iterator { 26 it := &memdbSnapIter{ 27 memdbIterator: &memdbIterator{ 28 EDB: EDB, 29 start: start, 30 end: end, 31 }, 32 cp: EDB.getSnapshot(), 33 } 34 it.init() 35 return it 36 } 37 38 func (EDB *memdb) getSnapshot() memdbCheckpoint { 39 if len(EDB.stages) > 0 { 40 return EDB.stages[0] 41 } 42 return EDB.vlog.checkpoint() 43 } 44 45 type memdbSnapGetter struct { 46 EDB *memdb 47 cp memdbCheckpoint 48 } 49 50 func (snap *memdbSnapGetter) Get(_ context.Context, key Key) ([]byte, error) { 51 x := snap.EDB.traverse(key, false) 52 if x.isNull() { 53 return nil, ErrNotExist 54 } 55 if x.vptr.isNull() { 56 // A flag only key, act as value not exists 57 return nil, ErrNotExist 58 } 59 v, ok := snap.EDB.vlog.getSnapshotValue(x.vptr, &snap.cp) 60 if !ok { 61 return nil, ErrNotExist 62 } 63 return v, nil 64 } 65 66 type memdbSnapIter struct { 67 *memdbIterator 68 value []byte 69 cp memdbCheckpoint 70 } 71 72 func (i *memdbSnapIter) Value() []byte { 73 return i.value 74 } 75 76 func (i *memdbSnapIter) Next() error { 77 i.value = nil 78 for i.Valid() { 79 if err := i.memdbIterator.Next(); err != nil { 80 return err 81 } 82 if i.setValue() { 83 return nil 84 } 85 } 86 return nil 87 } 88 89 func (i *memdbSnapIter) setValue() bool { 90 if !i.Valid() { 91 return false 92 } 93 if v, ok := i.EDB.vlog.getSnapshotValue(i.curr.vptr, &i.cp); ok { 94 i.value = v 95 return true 96 } 97 return false 98 } 99 100 func (i *memdbSnapIter) init() { 101 if len(i.start) == 0 { 102 i.seekToFirst() 103 } else { 104 i.seek(i.start) 105 } 106 107 if !i.setValue() { 108 err := i.Next() 109 _ = err // memdbIterator will never fail 110 } 111 }