diff --git a/beacon/light/canonical.go b/beacon/light/canonical.go index c5b3c2ec14..381cfdfda1 100644 --- a/beacon/light/canonical.go +++ b/beacon/light/canonical.go @@ -102,23 +102,13 @@ func (cs *canonicalStore[T]) add(backend ethdb.KeyValueWriter, period uint64, va // deleteFrom removes items starting from the given period. func (cs *canonicalStore[T]) deleteFrom(batch ethdb.Batch, fromPeriod uint64) (deleted Range) { - if fromPeriod >= cs.periods.End { - return - } - if fromPeriod < cs.periods.Start { - fromPeriod = cs.periods.Start - } - deleted = Range{Start: fromPeriod, End: cs.periods.End} - for period := fromPeriod; period < cs.periods.End; period++ { + keepRange, deleteRange := cs.periods.Split(fromPeriod) + deleteRange.Each(func(period uint64) { batch.Delete(cs.databaseKey(period)) cs.cache.Remove(period) - } - if fromPeriod > cs.periods.Start { - cs.periods.End = fromPeriod - } else { - cs.periods = Range{} - } - return + }) + cs.periods = keepRange + return deleteRange } // get returns the item at the given period or the null value of the given type diff --git a/beacon/light/range.go b/beacon/light/range.go index e9427ed382..71b140c069 100644 --- a/beacon/light/range.go +++ b/beacon/light/range.go @@ -52,3 +52,27 @@ func (a *Range) Expand(period uint64) { a.End++ } } + +// Split splits the range into two ranges. The 'fromPeriod' will be the first +// element in the second range (if present). +// The original range is unchanged by this operation +func (a *Range) Split(fromPeriod uint64) (Range, Range) { + if fromPeriod <= a.Start { + // First range empty, everything in second range, + return Range{}, *a + } + if fromPeriod >= a.End { + // Second range empty, everything in first range, + return *a, Range{} + } + x := Range{a.Start, fromPeriod} + y := Range{fromPeriod, a.End} + return x, y +} + +// Each invokes the supplied function fn once per period in range +func (a *Range) Each(fn func(uint64)) { + for p := a.Start; p < a.End; p++ { + fn(p) + } +}