github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/graveler/committed/iterator.go (about) 1 package committed 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 8 "github.com/treeverse/lakefs/pkg/graveler" 9 ) 10 11 type iterator struct { 12 ctx context.Context 13 started bool 14 manager RangeManager 15 rangesIt ValueIterator 16 rng *Range // Decoded value at which rangeIt point 17 it graveler.ValueIterator // nil at start of range 18 err error 19 namespace Namespace 20 beforeRange bool 21 } 22 23 func NewIterator(ctx context.Context, manager RangeManager, namespace Namespace, rangesIt ValueIterator) Iterator { 24 return &iterator{ 25 ctx: ctx, 26 manager: manager, 27 namespace: namespace, 28 rangesIt: rangesIt, 29 } 30 } 31 32 // loadIt loads rvi.it to start iterating over a new range. It returns false and sets rvi.err 33 // if it fails to open the new range. 34 func (rvi *iterator) loadIt() bool { 35 it, err := rvi.manager.NewRangeIterator(rvi.ctx, rvi.namespace, rvi.rng.ID) 36 if err != nil { 37 rvi.err = fmt.Errorf("open range %s: %w", rvi.rng.ID, err) 38 return false 39 } 40 rvi.it = NewUnmarshalIterator(it) 41 return true 42 } 43 44 func (rvi *iterator) NextRange() bool { 45 if rvi.it != nil { 46 rvi.it.Close() 47 } 48 rvi.it = nil 49 rvi.rng = nil 50 51 var rngRecord *Record 52 for rngRecord == nil { // Skip this and any consecutive finished ranges. 53 if !rvi.rangesIt.Next() { 54 return false 55 } 56 rngRecord = rvi.rangesIt.Value() 57 } 58 59 gv, err := UnmarshalValue(rngRecord.Value) 60 if err != nil { 61 rvi.err = fmt.Errorf("unmarshal value for %s: %w", string(rngRecord.Key), err) 62 return false 63 } 64 65 rng, err := UnmarshalRange(gv.Data) 66 if err != nil { 67 rvi.err = fmt.Errorf("unmarshal %s: %w", string(rngRecord.Key), err) 68 return false 69 } 70 71 rng.ID = ID(gv.Identity) 72 rvi.rng = &rng 73 74 return true 75 } 76 77 func (rvi *iterator) Next() bool { 78 if rvi.err != nil { 79 return false 80 } 81 if rvi.beforeRange { 82 rvi.beforeRange = false 83 return true 84 } 85 if !rvi.started { 86 rvi.started = true 87 return rvi.NextRange() 88 } 89 if rvi.it != nil { 90 if rvi.it.Next() { 91 return true 92 } 93 // At end of range 94 return rvi.NextRange() 95 } 96 // Start iterating inside the range of rvi.RangesIt 97 if rvi.rng == nil { 98 return rvi.NextRange() 99 } 100 101 if !rvi.loadIt() { 102 return false 103 } 104 105 if rvi.it.Next() { 106 return true 107 } 108 // Already at end of empty range 109 return rvi.NextRange() 110 } 111 112 func (rvi *iterator) Value() (*graveler.ValueRecord, *Range) { 113 if rvi.it == nil { 114 return nil, rvi.rng // start new range 115 } 116 return rvi.it.Value(), rvi.rng 117 } 118 119 func (rvi *iterator) Err() error { 120 if rvi.err != nil { 121 return rvi.err 122 } 123 if rvi.it == nil { 124 return nil 125 } 126 return rvi.it.Err() 127 } 128 129 func (rvi *iterator) Close() { 130 rvi.rangesIt.Close() 131 if rvi.it == nil { 132 return 133 } 134 rvi.it.Close() 135 } 136 137 func (rvi *iterator) loadRange(key graveler.Key) bool { 138 rvi.rangesIt.SeekGE(Key(key)) 139 if err := rvi.rangesIt.Err(); err != nil { 140 rvi.err = err 141 return false 142 } 143 if !rvi.NextRange() { 144 return false // Reached end 145 } 146 rvi.started = true // "Started": rangesIt is valid. 147 if bytes.Compare(key, rvi.rng.MinKey) <= 0 { 148 // the given key is before the next range 149 rvi.beforeRange = true 150 return false 151 } 152 return rvi.loadIt() 153 } 154 155 func (rvi *iterator) SeekGE(key graveler.Key) { 156 if rvi.rng == nil || rvi.it == nil || bytes.Compare(key, rvi.rng.MinKey) < 0 || bytes.Compare(key, rvi.rng.MaxKey) > 0 { 157 // no current range, or new key outside current range boundaries 158 if !rvi.loadRange(key) { 159 return 160 } 161 } 162 rvi.it.SeekGE(key) 163 // Ready to call Next to see values. 164 rvi.err = rvi.it.Err() 165 } 166 167 type emptyIterator struct{} 168 169 func NewEmptyIterator() Iterator { 170 return &emptyIterator{} 171 } 172 173 func (e *emptyIterator) Next() bool { 174 return false 175 } 176 177 func (e *emptyIterator) NextRange() bool { 178 return false 179 } 180 181 func (e *emptyIterator) Value() (*graveler.ValueRecord, *Range) { 182 return nil, nil 183 } 184 185 func (e *emptyIterator) SeekGE(graveler.Key) {} 186 187 func (e *emptyIterator) Err() error { 188 return nil 189 } 190 191 func (e *emptyIterator) Close() {}