github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/storage/memdb_iterator.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 "bytes" 21 22 "github.com/vescale/zgraph/storage/kv" 23 ) 24 25 // MemDBIter is an Iterator with KeyFlags related functions. 26 type MemDBIter struct { 27 db *MemDB 28 curr memdbNodeAddr 29 start []byte 30 end []byte 31 reverse bool 32 includeFlags bool 33 } 34 35 // Iter creates an Iterator positioned on the first entry that k <= entry's key. 36 // If such entry is not found, it returns an invalid Iterator with no error. 37 // It yields only keys that < upperBound. If upperBound is nil, it means the upperBound is unbounded. 38 // The Iterator must be Closed after use. 39 func (db *MemDB) Iter(lowerBound, upperBound kv.Key) (kv.Iterator, error) { 40 i := &MemDBIter{ 41 db: db, 42 start: lowerBound, 43 end: upperBound, 44 } 45 i.init() 46 return i, nil 47 } 48 49 // IterReverse creates a reversed Iterator positioned on the first entry which key is less than k. 50 // The returned SnapshotIter will iterate from greater key to smaller key. 51 // If k is nil, the returned SnapshotIter will be positioned at the last key. 52 func (db *MemDB) IterReverse(lowerBound, upperBound kv.Key) (kv.Iterator, error) { 53 i := &MemDBIter{ 54 db: db, 55 start: lowerBound, 56 end: upperBound, 57 reverse: true, 58 } 59 i.init() 60 return i, nil 61 } 62 63 // IterWithFlags returns a MemDBIter. 64 func (db *MemDB) IterWithFlags(lowerBound []byte, upperBound []byte) *MemDBIter { 65 i := &MemDBIter{ 66 db: db, 67 start: lowerBound, 68 end: upperBound, 69 includeFlags: true, 70 } 71 i.init() 72 return i 73 } 74 75 // IterReverseWithFlags returns a reversed MemDBIter. 76 func (db *MemDB) IterReverseWithFlags(k []byte) *MemDBIter { 77 i := &MemDBIter{ 78 db: db, 79 end: k, 80 reverse: true, 81 includeFlags: true, 82 } 83 i.init() 84 return i 85 } 86 87 func (i *MemDBIter) init() { 88 if i.reverse { 89 if len(i.end) == 0 { 90 i.seekToLast() 91 } else { 92 i.seek(i.end) 93 } 94 } else { 95 if len(i.start) == 0 { 96 i.seekToFirst() 97 } else { 98 i.seek(i.start) 99 } 100 } 101 102 if i.isFlagsOnly() && !i.includeFlags { 103 err := i.Next() 104 _ = err // memdbIterator will never fail 105 } 106 } 107 108 // Valid returns true if the current SnapshotIter is valid. 109 func (i *MemDBIter) Valid() bool { 110 if !i.reverse { 111 return !i.curr.isNull() && (i.end == nil || bytes.Compare(i.Key(), i.end) < 0) 112 } 113 return !i.curr.isNull() 114 } 115 116 // Flags returns flags belong to current SnapshotIter. 117 func (i *MemDBIter) Flags() kv.KeyFlags { 118 return i.curr.getKeyFlags() 119 } 120 121 // UpdateFlags updates and apply with flagsOp. 122 func (i *MemDBIter) UpdateFlags(ops ...kv.FlagsOp) { 123 origin := i.curr.getKeyFlags() 124 n := kv.ApplyFlagsOps(origin, ops...) 125 i.curr.setKeyFlags(n) 126 } 127 128 // HasValue returns false if it is flags only. 129 func (i *MemDBIter) HasValue() bool { 130 return !i.isFlagsOnly() 131 } 132 133 // Key returns current key. 134 func (i *MemDBIter) Key() kv.Key { 135 return i.curr.getKey() 136 } 137 138 // Handle returns MemKeyHandle with the current position. 139 func (i *MemDBIter) Handle() MemKeyHandle { 140 return MemKeyHandle{ 141 idx: uint16(i.curr.addr.idx), 142 off: i.curr.addr.off, 143 } 144 } 145 146 // Value returns the value. 147 func (i *MemDBIter) Value() []byte { 148 return i.db.vlog.getValue(i.curr.vptr) 149 } 150 151 // Next goes the next position. 152 func (i *MemDBIter) Next() error { 153 for { 154 if i.reverse { 155 i.curr = i.db.predecessor(i.curr) 156 } else { 157 i.curr = i.db.successor(i.curr) 158 } 159 160 // We need to skip persistent flags only nodes. 161 if i.includeFlags || !i.isFlagsOnly() { 162 break 163 } 164 } 165 return nil 166 } 167 168 // Close closes the current SnapshotIter. 169 func (i *MemDBIter) Close() {} 170 171 func (i *MemDBIter) seekToFirst() { 172 y := memdbNodeAddr{nil, nullAddr} 173 x := i.db.getNode(i.db.root) 174 175 for !x.isNull() { 176 y = x 177 x = y.getLeft(i.db) 178 } 179 180 i.curr = y 181 } 182 183 func (i *MemDBIter) seekToLast() { 184 y := memdbNodeAddr{nil, nullAddr} 185 x := i.db.getNode(i.db.root) 186 187 for !x.isNull() { 188 y = x 189 x = y.getRight(i.db) 190 } 191 192 i.curr = y 193 } 194 195 func (i *MemDBIter) seek(key []byte) { 196 y := memdbNodeAddr{nil, nullAddr} 197 x := i.db.getNode(i.db.root) 198 199 var cmp int 200 for !x.isNull() { 201 y = x 202 cmp = bytes.Compare(key, y.getKey()) 203 204 if cmp < 0 { 205 x = y.getLeft(i.db) 206 } else if cmp > 0 { 207 x = y.getRight(i.db) 208 } else { 209 break 210 } 211 } 212 213 if !i.reverse { 214 if cmp > 0 { 215 // Move to next 216 i.curr = i.db.successor(y) 217 return 218 } 219 i.curr = y 220 return 221 } 222 223 if cmp <= 0 && !y.isNull() { 224 i.curr = i.db.predecessor(y) 225 return 226 } 227 i.curr = y 228 } 229 230 func (i *MemDBIter) isFlagsOnly() bool { 231 return !i.curr.isNull() && i.curr.vptr.isNull() 232 }