github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/graveler/committed/meta_range.go (about) 1 package committed 2 3 //go:generate go run github.com/golang/mock/mockgen@v1.6.0 -source=meta_range.go -destination=mock/meta_range.go -package=mock 4 5 import ( 6 "context" 7 8 "github.com/treeverse/lakefs/pkg/graveler" 9 ) 10 11 // Iterator iterates over all Range headers and values of a MetaRange, allowing seeking by entire 12 // ranges. 13 type Iterator interface { 14 // Next moves to look at the next value in the current Range, or a header for the next 15 // Range if the current Range is over. 16 Next() bool 17 // NextRange skips the current Range and continues at the header for the next Range. 18 NextRange() bool 19 // Value returns a nil ValueRecord and a Range before starting a Range, or a Value and 20 // that Range when inside a Range. 21 Value() (*graveler.ValueRecord, *Range) 22 SeekGE(id graveler.Key) 23 Err() error 24 Close() 25 } 26 27 // DiffIterator iterates over all Range headers and values of a Diff, allowing seeking by entire 28 // ranges. 29 // DiffIterator might contain ranges without headers 30 // for example: 31 // 32 // left [min].R1.[max] [min].R3.[max] [min]...............R5..............[max] 33 // 34 // ------------------------------------------------------------------------------------------------ 35 // 36 // right [min].R2.[max] [min.....R4....max] [min].R6.[max] [min].R7.[max] 37 // 38 // R1 - will return as diff with header 39 // R2 - will return as diff with header 40 // R3 and R4 - could not return a header because we must enter the ranges in order to get some header values (such as count) 41 // R5 and R6 - same as R3 and R4 42 // R7 - in case R5 has no values in the R7 range, R7 would return as a diff with header 43 type DiffIterator interface { 44 // Next moves to look at the next value in the current Range, or a header for the next Range if the current Range is over and a next range exists. 45 Next() bool 46 // NextRange skips the current range 47 // If the next Range is a "headerless" range it will return the first value, otherwise will return the header 48 // calling NextRange from a "headerless" should result with ErrNoRange 49 NextRange() bool 50 // Value returns a nil ValueRecord and a Range before starting a Range, a Value and that Range when inside a Range, or a value with no range when inside a headerless Range 51 Value() (*graveler.Diff, *RangeDiff) 52 SeekGE(id graveler.Key) 53 Err() error 54 Close() 55 } 56 57 // RangeDiff represents a change in Range 58 type RangeDiff struct { 59 Type graveler.DiffType 60 Range *Range 61 LeftIdentity ID // the Identity of the value on the left side of the diff (populated on DiffTypeChanged ) 62 } 63 64 func (r RangeDiff) Copy() *RangeDiff { 65 res := RangeDiff{ 66 Type: r.Type, 67 } 68 if r.Range != nil { 69 res.Range = r.Range.Copy() 70 } 71 return &res 72 } 73 74 // MetaRangeManager is an abstraction for a repository of MetaRanges that exposes operations on them 75 type MetaRangeManager interface { 76 Exists(ctx context.Context, ns graveler.StorageNamespace, id graveler.MetaRangeID) (bool, error) 77 78 // GetValue returns the matching in-range graveler.ValueRecord for key in the 79 // MetaRange with id. 80 GetValue(ctx context.Context, ns graveler.StorageNamespace, id graveler.MetaRangeID, key graveler.Key) (*graveler.ValueRecord, error) 81 82 // NewWriter returns a writer that is used for creating new MetaRanges 83 NewWriter(ctx context.Context, ns graveler.StorageNamespace, metadata graveler.Metadata) MetaRangeWriter 84 85 // NewMetaRangeIterator returns an Iterator over the MetaRange with id. 86 NewMetaRangeIterator(ctx context.Context, ns graveler.StorageNamespace, metaRangeID graveler.MetaRangeID) (Iterator, error) 87 88 // GetMetaRangeURI returns a URI with an object representing metarange ID. It may 89 // return a URI that does not resolve (rather than an error) if ID does not exist. 90 GetMetaRangeURI(ctx context.Context, ns graveler.StorageNamespace, metaRangeID graveler.MetaRangeID) (string, error) 91 92 // GetRangeURI returns a URI with an object representing range ID. It may 93 // return a URI that does not resolve (rather than an error) if ID does not exist. 94 GetRangeURI(ctx context.Context, ns graveler.StorageNamespace, rangeID graveler.RangeID) (string, error) 95 96 // GetRangeByKey returns the Range that contains key in the MetaRange with id. 97 GetRangeByKey(ctx context.Context, ns graveler.StorageNamespace, id graveler.MetaRangeID, key graveler.Key) (*Range, error) 98 } 99 100 // MetaRangeWriter is an abstraction for creating new MetaRanges 101 type MetaRangeWriter interface { 102 // WriteRecord adds a record to the MetaRange. The key must be greater than any other key that was written 103 // (in other words - values must be entered sorted by key order). 104 // If the most recent insertion was using WriteRange, the key must be greater than any key in the added ranges. 105 WriteRecord(graveler.ValueRecord) error 106 107 // WriteRange adds a complete range to the MetaRange at the current insertion point. 108 // Added Range must not contain keys smaller than last previously written value. 109 WriteRange(Range) error 110 111 // Close finalizes the MetaRange creation. It's invalid to add records after calling this method. 112 // During MetaRange writing, ranges are closed asynchronously and copied by tierFS 113 // while writing continues. Close waits until closing and copying all ranges. 114 Close(context.Context) (*graveler.MetaRangeID, error) 115 116 Abort() error 117 }