github.com/coocood/badger@v1.5.1-0.20200528065104-c02ac3616d04/table/merge_iterator.go (about) 1 package table 2 3 import ( 4 "bytes" 5 6 "github.com/coocood/badger/y" 7 ) 8 9 // MergeTowIterator is a specialized MergeIterator that only merge tow iterators. 10 // It is an optimization for compaction. 11 type MergeIterator struct { 12 smaller *mergeIteratorChild 13 bigger *mergeIteratorChild 14 15 // when the two iterators has the same value, the value in the second iterator is ignored. 16 second y.Iterator 17 reverse bool 18 sameKey bool 19 } 20 21 type mergeIteratorChild struct { 22 valid bool 23 key y.Key 24 iter y.Iterator 25 26 // The two iterators are type asserted from `y.Iterator`, used to inline more function calls. 27 merge *MergeIterator 28 concat *ConcatIterator 29 } 30 31 func (child *mergeIteratorChild) setIterator(iter y.Iterator) { 32 child.iter = iter 33 child.merge, _ = iter.(*MergeIterator) 34 child.concat, _ = iter.(*ConcatIterator) 35 } 36 37 func (child *mergeIteratorChild) reset() { 38 if child.merge != nil { 39 child.valid = child.merge.smaller.valid 40 if child.valid { 41 child.key = child.merge.smaller.key 42 } 43 } else if child.concat != nil { 44 child.valid = child.concat.Valid() 45 if child.valid { 46 child.key = child.concat.Key() 47 } 48 } else { 49 child.valid = child.iter.Valid() 50 if child.valid { 51 child.key = child.iter.Key() 52 } 53 } 54 } 55 56 func (mt *MergeIterator) fix() { 57 if !mt.bigger.valid { 58 return 59 } 60 for mt.smaller.valid { 61 cmp := bytes.Compare(mt.smaller.key.UserKey, mt.bigger.key.UserKey) 62 if cmp == 0 { 63 mt.sameKey = true 64 if mt.smaller.iter == mt.second { 65 mt.swap() 66 } 67 return 68 } 69 mt.sameKey = false 70 if mt.reverse { 71 if cmp < 0 { 72 mt.swap() 73 } 74 } else { 75 if cmp > 0 { 76 mt.swap() 77 } 78 } 79 return 80 } 81 mt.swap() 82 } 83 84 func (mt *MergeIterator) swap() { 85 mt.smaller, mt.bigger = mt.bigger, mt.smaller 86 } 87 88 // Next returns the next element. If it is the same as the current key, ignore it. 89 func (mt *MergeIterator) Next() { 90 if mt.smaller.merge != nil { 91 mt.smaller.merge.Next() 92 } else if mt.smaller.concat != nil { 93 mt.smaller.concat.Next() 94 } else { 95 mt.smaller.iter.Next() 96 } 97 mt.smaller.reset() 98 if mt.sameKey && mt.bigger.valid { 99 if mt.bigger.merge != nil { 100 mt.bigger.merge.Next() 101 } else if mt.bigger.concat != nil { 102 mt.bigger.concat.Next() 103 } else { 104 mt.bigger.iter.Next() 105 } 106 mt.bigger.reset() 107 } 108 mt.fix() 109 } 110 111 func (mt *MergeIterator) NextVersion() bool { 112 if mt.smaller.iter.NextVersion() { 113 mt.smaller.reset() 114 return true 115 } 116 if !mt.sameKey { 117 return false 118 } 119 if !mt.bigger.valid { 120 return false 121 } 122 if mt.smaller.key.Version < mt.bigger.key.Version { 123 // The smaller is second iterator, the bigger is first iterator. 124 // We have swapped already, no more versions. 125 return false 126 } 127 if mt.smaller.key.Version == mt.bigger.key.Version { 128 // have duplicated key in the two iterators. 129 if mt.bigger.iter.NextVersion() { 130 mt.bigger.reset() 131 mt.swap() 132 return true 133 } 134 return false 135 } 136 mt.swap() 137 return true 138 } 139 140 // Rewind seeks to first element (or last element for reverse iterator). 141 func (mt *MergeIterator) Rewind() { 142 mt.smaller.iter.Rewind() 143 mt.smaller.reset() 144 mt.bigger.iter.Rewind() 145 mt.bigger.reset() 146 mt.fix() 147 } 148 149 // Seek brings us to element with key >= given key. 150 func (mt *MergeIterator) Seek(key []byte) { 151 mt.smaller.iter.Seek(key) 152 mt.smaller.reset() 153 mt.bigger.iter.Seek(key) 154 mt.bigger.reset() 155 mt.fix() 156 } 157 158 // Valid returns whether the MergeIterator is at a valid element. 159 func (mt *MergeIterator) Valid() bool { 160 return mt.smaller.valid 161 } 162 163 // Key returns the key associated with the current iterator 164 func (mt *MergeIterator) Key() y.Key { 165 return mt.smaller.key 166 } 167 168 // Value returns the value associated with the iterator. 169 func (mt *MergeIterator) Value() y.ValueStruct { 170 return mt.smaller.iter.Value() 171 } 172 173 func (mt *MergeIterator) FillValue(vs *y.ValueStruct) { 174 if mt.smaller.merge != nil { 175 mt.smaller.merge.FillValue(vs) 176 } else if mt.smaller.concat != nil { 177 mt.smaller.concat.FillValue(vs) 178 } else { 179 mt.smaller.iter.FillValue(vs) 180 } 181 } 182 183 // NewMergeIterator creates a merge iterator 184 func NewMergeIterator(iters []y.Iterator, reverse bool) y.Iterator { 185 if len(iters) == 0 { 186 return &EmptyIterator{} 187 } else if len(iters) == 1 { 188 return iters[0] 189 } else if len(iters) == 2 { 190 mi := &MergeIterator{ 191 second: iters[1], 192 reverse: reverse, 193 smaller: new(mergeIteratorChild), 194 bigger: new(mergeIteratorChild), 195 } 196 mi.smaller.setIterator(iters[0]) 197 mi.bigger.setIterator(iters[1]) 198 return mi 199 } 200 mid := len(iters) / 2 201 return NewMergeIterator([]y.Iterator{NewMergeIterator(iters[:mid], reverse), NewMergeIterator(iters[mid:], reverse)}, reverse) 202 } 203 204 type EmptyIterator struct{} 205 206 func (e *EmptyIterator) Next() {} 207 208 func (e *EmptyIterator) NextVersion() bool { 209 return false 210 } 211 212 func (e *EmptyIterator) Rewind() {} 213 214 func (e *EmptyIterator) Seek(key []byte) {} 215 216 func (e *EmptyIterator) Key() y.Key { 217 return y.Key{} 218 } 219 220 func (e *EmptyIterator) Value() y.ValueStruct { 221 return y.ValueStruct{} 222 } 223 224 func (e *EmptyIterator) FillValue(vs *y.ValueStruct) {} 225 226 func (e *EmptyIterator) Valid() bool { 227 return false 228 }