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  }