github.com/pingcap/badger@v1.5.1-0.20230103063557-828f39b09b6d/y/iterator.go (about) 1 /* 2 * Copyright 2017 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package y 18 19 import ( 20 "encoding/binary" 21 ) 22 23 // ValueStruct represents the value info that can be associated with a key, but also the internal 24 // Meta field. 25 type ValueStruct struct { 26 Meta byte 27 UserMeta []byte 28 Value []byte 29 30 Version uint64 // This field is not serialized. Only for internal usage. 31 } 32 33 // EncodedSize is the size of the ValueStruct when encoded 34 func (v *ValueStruct) EncodedSize() uint32 { 35 return uint32(len(v.Value) + len(v.UserMeta) + 2 + 8) // meta 36 } 37 38 // Decode uses the length of the slice to infer the length of the Value field. 39 func (v *ValueStruct) Decode(b []byte) { 40 v.Version = binary.LittleEndian.Uint64(b) 41 b = b[8:] 42 v.Meta = b[0] 43 v.UserMeta = nil 44 userMetaEnd := 2 + b[1] 45 if b[1] != 0 { 46 v.UserMeta = b[2:userMetaEnd] 47 } 48 v.Value = b[userMetaEnd:] 49 } 50 51 // Encode expects a slice of length at least v.EncodedSize(). 52 func (v *ValueStruct) Encode(b []byte) { 53 binary.LittleEndian.PutUint64(b, v.Version) 54 b = b[8:] 55 b[0] = v.Meta 56 b[1] = byte(len(v.UserMeta)) 57 copy(b[2:], v.UserMeta) 58 copy(b[2+len(v.UserMeta):], v.Value) 59 } 60 61 // Valid checks if the ValueStruct is valid. 62 func (v *ValueStruct) Valid() bool { 63 return v.Meta != 0 || v.Value != nil 64 } 65 66 // EncodeTo should be kept in sync with the Encode function above. The reason 67 // this function exists is to avoid creating byte arrays per key-value pair in 68 // table/builder.go. 69 func (v *ValueStruct) EncodeTo(buf []byte) []byte { 70 tmp := make([]byte, 8) 71 binary.LittleEndian.PutUint64(tmp, v.Version) 72 buf = append(buf, tmp...) 73 buf = append(buf, v.Meta, byte(len(v.UserMeta))) 74 buf = append(buf, v.UserMeta...) 75 buf = append(buf, v.Value...) 76 return buf 77 } 78 79 // Iterator is an interface for a basic iterator. 80 type Iterator interface { 81 // Next returns the next entry with different key on the latest version. 82 // If old version is needed, call NextVersion. 83 Next() 84 // NextVersion set the current entry to an older version. 85 // The iterator must be valid to call this method. 86 // It returns true if there is an older version, returns false if there is no older version. 87 // The iterator is still valid and on the same key. 88 NextVersion() bool 89 Rewind() 90 Seek(key []byte) 91 Key() Key 92 Value() ValueStruct 93 FillValue(vs *ValueStruct) 94 Valid() bool 95 Close() error 96 } 97 98 // SeekToVersion seeks a valid Iterator to the version that <= the given version. 99 func SeekToVersion(it Iterator, version uint64) bool { 100 if version >= it.Key().Version { 101 return true 102 } 103 for it.NextVersion() { 104 if version >= it.Key().Version { 105 return true 106 } 107 } 108 return false 109 } 110 111 func NextAllVersion(it Iterator) { 112 if !it.NextVersion() { 113 it.Next() 114 } 115 }