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 }