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