github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/internal/rangedel/iter.go (about) 1 // Copyright 2018 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package rangedel 6 7 import "github.com/petermattis/pebble/internal/base" 8 9 // Iter is an iterator over a set of fragmented tombstones. 10 type Iter struct { 11 cmp base.Compare 12 tombstones []Tombstone 13 index int 14 } 15 16 // NewIter returns a new iterator over a set of fragmented tombstones. 17 func NewIter(cmp base.Compare, tombstones []Tombstone) *Iter { 18 return &Iter{ 19 cmp: cmp, 20 tombstones: tombstones, 21 index: -1, 22 } 23 } 24 25 // SeekGE implements internalIterator.SeekGE, as documented in the pebble 26 // package. 27 func (i *Iter) SeekGE(key []byte) (*base.InternalKey, []byte) { 28 // NB: manually inlined sort.Seach is ~5% faster. 29 // 30 // Define f(-1) == false and f(n) == true. 31 // Invariant: f(index-1) == false, f(upper) == true. 32 ikey := base.MakeSearchKey(key) 33 i.index = 0 34 upper := len(i.tombstones) 35 for i.index < upper { 36 h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h 37 // i.index ≤ h < upper 38 if base.InternalCompare(i.cmp, ikey, i.tombstones[h].Start) >= 0 { 39 i.index = h + 1 // preserves f(i-1) == false 40 } else { 41 upper = h // preserves f(j) == true 42 } 43 } 44 // i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) == 45 // true => answer is i.index. 46 if i.index >= len(i.tombstones) { 47 return nil, nil 48 } 49 t := &i.tombstones[i.index] 50 return &t.Start, t.End 51 } 52 53 func (i *Iter) SeekPrefixGE(prefix, key []byte) (*base.InternalKey, []byte) { 54 // This should never be called as prefix iteration is only done for point records. 55 panic("pebble: SeekPrefixGE unimplemented") 56 } 57 58 // SeekLT implements internalIterator.SeekLT, as documented in the pebble 59 // package. 60 func (i *Iter) SeekLT(key []byte) (*base.InternalKey, []byte) { 61 // NB: manually inlined sort.Search is ~5% faster. 62 // 63 // Define f(-1) == false and f(n) == true. 64 // Invariant: f(index-1) == false, f(upper) == true. 65 ikey := base.MakeSearchKey(key) 66 i.index = 0 67 upper := len(i.tombstones) 68 for i.index < upper { 69 h := int(uint(i.index+upper) >> 1) // avoid overflow when computing h 70 // i.index ≤ h < upper 71 if base.InternalCompare(i.cmp, ikey, i.tombstones[h].Start) > 0 { 72 i.index = h + 1 // preserves f(i-1) == false 73 } else { 74 upper = h // preserves f(j) == true 75 } 76 } 77 // i.index == upper, f(i.index-1) == false, and f(upper) (= f(i.index)) == 78 // true => answer is i.index. 79 80 // Since keys are strictly increasing, if i.index > 0 then i.index-1 will be 81 // the largest whose key is < the key sought. 82 i.index-- 83 if i.index < 0 { 84 return nil, nil 85 } 86 t := &i.tombstones[i.index] 87 return &t.Start, t.End 88 } 89 90 // First implements internalIterator.First, as documented in the pebble 91 // package. 92 func (i *Iter) First() (*base.InternalKey, []byte) { 93 if len(i.tombstones) == 0 { 94 return nil, nil 95 } 96 i.index = 0 97 t := &i.tombstones[i.index] 98 return &t.Start, t.End 99 } 100 101 // Last implements internalIterator.Last, as documented in the pebble 102 // package. 103 func (i *Iter) Last() (*base.InternalKey, []byte) { 104 if len(i.tombstones) == 0 { 105 return nil, nil 106 } 107 i.index = len(i.tombstones) - 1 108 t := &i.tombstones[i.index] 109 return &t.Start, t.End 110 } 111 112 // Next implements internalIterator.Next, as documented in the pebble 113 // package. 114 func (i *Iter) Next() (*base.InternalKey, []byte) { 115 if i.index == len(i.tombstones) { 116 return nil, nil 117 } 118 i.index++ 119 if i.index == len(i.tombstones) { 120 return nil, nil 121 } 122 t := &i.tombstones[i.index] 123 return &t.Start, t.End 124 } 125 126 // Prev implements internalIterator.Prev, as documented in the pebble 127 // package. 128 func (i *Iter) Prev() (*base.InternalKey, []byte) { 129 if i.index < 0 { 130 return nil, nil 131 } 132 i.index-- 133 if i.index < 0 { 134 return nil, nil 135 } 136 t := &i.tombstones[i.index] 137 return &t.Start, t.End 138 } 139 140 // Key implements internalIterator.Key, as documented in the pebble 141 // package. 142 func (i *Iter) Key() *base.InternalKey { 143 return &i.tombstones[i.index].Start 144 } 145 146 // Value implements internalIterator.Value, as documented in the pebble 147 // package. 148 func (i *Iter) Value() []byte { 149 return i.tombstones[i.index].End 150 } 151 152 // Valid implements internalIterator.Valid, as documented in the pebble 153 // package. 154 func (i *Iter) Valid() bool { 155 return i.index >= 0 && i.index < len(i.tombstones) 156 } 157 158 // Error implements internalIterator.Error, as documented in the pebble 159 // package. 160 func (i *Iter) Error() error { 161 return nil 162 } 163 164 // Close implements internalIterator.Close, as documented in the pebble 165 // package. 166 func (i *Iter) Close() error { 167 return nil 168 } 169 170 // SetBounds implements internalIterator.SetBounds, as documented in the pebble 171 // package. 172 func (i *Iter) SetBounds(lower, upper []byte) { 173 // This should never be called as bounds are only used for point records. 174 panic("pebble: SetBounds unimplemented") 175 }