Skip to content

Commit

Permalink
refactor: Rework core.Spans (sourcenetwork#3210)
Browse files Browse the repository at this point in the history
## Relevant issue(s)

Resolves sourcenetwork#3209

## Description

Simplifies core.Spans a little bit, before removing some old hacky code
allowing a nicer way of handling headstore keys within the
planner/fetcher system.
  • Loading branch information
AndrewSisley authored Nov 6, 2024
1 parent c8fd3b1 commit 6d6c9f2
Show file tree
Hide file tree
Showing 41 changed files with 379 additions and 389 deletions.
80 changes: 24 additions & 56 deletions internal/core/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,22 @@ import (
)

// Span is a range of keys from [Start, End).
type Span interface {
// Start returns the starting key of the Span.
Start() keys.DataStoreKey
// End returns the ending key of the Span.
End() keys.DataStoreKey
// Compare returns -1 if the provided span is less, 0 if it is equal, and 1 if its greater.
Compare(Span) SpanComparisonResult
}
type Span struct {
// Start represents the starting key of the Span.
Start keys.Walkable

type span struct {
start keys.DataStoreKey
end keys.DataStoreKey
// End represents the ending key of the Span.
End keys.Walkable
}

var _ Span = span{}

// NewSpan creates a new Span from the provided start and end keys.
func NewSpan(start, end keys.DataStoreKey) Span {
return span{
start: start,
end: end,
func NewSpan(start, end keys.Walkable) Span {
return Span{
Start: start,
End: end,
}
}

// Start returns the starting key of the Span.
func (s span) Start() keys.DataStoreKey {
return s.start
}

// End returns the ending key of the Span.
func (s span) End() keys.DataStoreKey {
return s.end
}

// SpanComparisonResult is the result of comparing two spans.
type SpanComparisonResult uint

Expand All @@ -73,18 +55,18 @@ const (
// Compares two spans returning how the compare to each other.
// If the end of one span is adjacent to the other (with no gap possible)
// then those ends are considered equal.
func (this span) Compare(other Span) SpanComparisonResult {
func (this Span) Compare(other Span) SpanComparisonResult {
if this == other {
return Equal
}

thisStart := this.start.ToString()
thisEnd := this.end.ToString()
otherStart := other.Start().ToString()
otherEnd := other.End().ToString()
thisStart := this.Start.ToString()
thisEnd := this.End.ToString()
otherStart := other.Start.ToString()
otherEnd := other.End.ToString()

if thisStart < otherStart {
if thisEnd == otherStart || isAdjacent(this.end, other.Start()) {
if thisEnd == otherStart || isAdjacent(this.End, other.Start) {
return StartBeforeEndEqualToStart
}

Expand Down Expand Up @@ -133,33 +115,19 @@ func (this span) Compare(other Span) SpanComparisonResult {
}
}

if thisStart == otherEnd || isAdjacent(this.start, other.End()) {
if thisStart == otherEnd || isAdjacent(this.Start, other.End) {
return StartEqualToEndEndAfter
}

return After
}

func isAdjacent(this keys.DataStoreKey, other keys.DataStoreKey) bool {
func isAdjacent(this keys.Walkable, other keys.Walkable) bool {
return len(this.ToString()) == len(other.ToString()) &&
(this.PrefixEnd().ToString() == other.ToString() ||
this.ToString() == other.PrefixEnd().ToString())
}

// Spans is a collection of individual spans.
type Spans struct {
HasValue bool
Value []Span
}

// NewSpans creates a new Spans from the provided spans.
func NewSpans(spans ...Span) Spans {
return Spans{
HasValue: true,
Value: spans,
}
}

// Merges an unordered, potentially overlapping and/or duplicated collection of Spans into
// a unique set in ascending order, where overlapping spans are merged into a single span.
// Will handle spans with keys of different lengths, where one might be a prefix of another.
Expand All @@ -186,7 +154,7 @@ func MergeAscending(spans []Span) []Span {
}

// Then we insert
newArray[i] = NewSpan(span.Start(), span.End())
newArray[i] = NewSpan(span.Start, span.End)

// Move the values prior to the new one across
for j := 0; j < i; j++ {
Expand All @@ -197,12 +165,12 @@ func MergeAscending(spans []Span) []Span {
// Exit the unique-span loop, this span has been handled
i = len(uniqueSpans)
case StartBeforeEndEqualToStart, StartBeforeEndWithin, StartBeforeEndEqual:
uniqueSpans[i] = NewSpan(span.Start(), uniqueSpan.End())
uniqueSpans[i] = NewSpan(span.Start, uniqueSpan.End)
uniqueSpanFound = true
i++
case StartBeforeEndAfter:
uniqueSpans = removeBefore(uniqueSpans, i, span.End().ToString())
uniqueSpans[i] = NewSpan(span.Start(), span.End())
uniqueSpans = removeBefore(uniqueSpans, i, span.End.ToString())
uniqueSpans[i] = NewSpan(span.Start, span.End)
uniqueSpanFound = true
// Exit the unique-span loop, this span has been handled
i = len(uniqueSpans)
Expand All @@ -211,8 +179,8 @@ func MergeAscending(spans []Span) []Span {
// Do nothing, span is contained within an existing unique-span
i = len(uniqueSpans)
case StartEqualEndAfter, StartWithinEndAfter, StartEqualToEndEndAfter:
uniqueSpans = removeBefore(uniqueSpans, i, span.End().ToString())
uniqueSpans[i] = NewSpan(uniqueSpan.Start(), span.End())
uniqueSpans = removeBefore(uniqueSpans, i, span.End.ToString())
uniqueSpans[i] = NewSpan(uniqueSpan.Start, span.End)
uniqueSpanFound = true
// Exit the unique-span loop, this span has been handled
i = len(uniqueSpans)
Expand All @@ -234,7 +202,7 @@ func MergeAscending(spans []Span) []Span {
func removeBefore(spans []Span, startIndex int, end string) []Span {
indexOfLastMatchingItem := -1
for i := startIndex; i < len(spans); i++ {
if spans[i].End().ToString() <= end {
if spans[i].End.ToString() <= end {
indexOfLastMatchingItem = i
}
}
Expand Down
Loading

0 comments on commit 6d6c9f2

Please sign in to comment.