github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/graveler/retention/starting_point_iterator.go (about)

     1  package retention
     2  
     3  import "github.com/treeverse/lakefs/pkg/graveler"
     4  
     5  // A GCStartingPoint represents a commit from which the GC algorithm should start scanning.
     6  // It could be either a branch HEAD, or a dangling commit.
     7  // The CommitID field is always set, while BranchID is set only if the commit is a branch HEAD.
     8  type GCStartingPoint struct {
     9  	BranchID graveler.BranchID
    10  	CommitID graveler.CommitID
    11  }
    12  
    13  // GCStartingPointIterator combines a branch iterator and a commit iterator. Both are assumed to be sorted and to contain no duplicates.
    14  // Each returned GCStartingPoint object contains the commit id. If the entry came from the branch iterator, it also contains the branch id.
    15  // Commits appearing in both iterators appear only once and include the branch id.
    16  // Closing this iterator will close the two internal iterators.
    17  type GCStartingPointIterator struct {
    18  	commitIterator graveler.CommitIterator
    19  	branchIterator graveler.BranchIterator
    20  
    21  	commitValue *graveler.CommitRecord
    22  	branchValue *graveler.BranchRecord
    23  	value       *GCStartingPoint
    24  }
    25  
    26  func NewGCStartingPointIterator(commitIterator graveler.CommitIterator, branchIterator graveler.BranchIterator) *GCStartingPointIterator {
    27  	return &GCStartingPointIterator{commitIterator: commitIterator, branchIterator: branchIterator}
    28  }
    29  
    30  func (sp *GCStartingPointIterator) Next() bool {
    31  	if sp.branchValue == nil && sp.branchIterator.Next() {
    32  		sp.branchValue = sp.branchIterator.Value()
    33  	}
    34  	if sp.commitValue == nil && sp.commitIterator.Next() {
    35  		sp.commitValue = sp.commitIterator.Value()
    36  	}
    37  	if sp.branchValue == nil && sp.commitValue == nil {
    38  		return false
    39  	}
    40  	if sp.branchValue != nil && sp.commitValue != nil && sp.branchValue.CommitID == sp.commitValue.CommitID {
    41  		// commit is same as branch head - skip the commit
    42  		sp.commitValue = nil
    43  	}
    44  	if sp.commitValue == nil || (sp.branchValue != nil && sp.commitValue.CommitID > sp.branchValue.CommitID) {
    45  		// has only branch, or branch is before commit
    46  		sp.value = &GCStartingPoint{
    47  			BranchID: sp.branchValue.BranchID,
    48  			CommitID: sp.branchValue.CommitID,
    49  		}
    50  		sp.branchValue = nil
    51  		return true
    52  	}
    53  	if sp.branchValue == nil || sp.commitValue.CommitID < sp.branchValue.CommitID {
    54  		// has only commit, or commit is before branch
    55  		sp.value = &GCStartingPoint{
    56  			CommitID: sp.commitValue.CommitID,
    57  		}
    58  		sp.commitValue = nil
    59  		return true
    60  	}
    61  	return false
    62  }
    63  
    64  func (sp *GCStartingPointIterator) Value() *GCStartingPoint {
    65  	return sp.value
    66  }
    67  
    68  func (sp *GCStartingPointIterator) Err() error {
    69  	if sp.branchIterator != nil {
    70  		return sp.branchIterator.Err()
    71  	}
    72  	return sp.commitIterator.Err()
    73  }
    74  
    75  func (sp *GCStartingPointIterator) Close() {
    76  	sp.commitIterator.Close()
    77  	sp.branchIterator.Close()
    78  }