From 1c7bcd1c03f1697d36f53b54476921309ccc9396 Mon Sep 17 00:00:00 2001 From: Radu Berinde Date: Fri, 29 Mar 2024 11:50:12 -0700 Subject: [PATCH] manifest: add a helper for iterating through all levels This helper can be used when we need to use an iterator for each L0 sublevel and for each level L1+. --- ingest_test.go | 24 +++++------------------- internal/manifest/version.go | 11 +++++++++++ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/ingest_test.go b/ingest_test.go index 0d1ecfe709..c2f1639eba 100644 --- a/ingest_test.go +++ b/ingest_test.go @@ -804,30 +804,16 @@ func TestExcise(t *testing.T) { d.mu.versions.logLock() d.mu.Unlock() current := d.mu.versions.currentVersion() - for _, sublevel := range current.L0Sublevels.Levels { - iter := sublevel.Iter() - for m := iter.SeekGE(d.cmp, exciseSpan.Start); m != nil && d.cmp(m.Smallest.UserKey, exciseSpan.End) < 0; m = iter.Next() { - _, err := d.excise(exciseSpan.UserKeyBounds(), m, ve, 0 /* level */) - if err != nil { - d.mu.Lock() - d.mu.versions.logUnlock() - d.mu.Unlock() - return fmt.Sprintf("error when excising %s: %s", m.FileNum, err.Error()) - } - } - } - for level := 1; level < manifest.NumLevels; level++ { - iter := current.Levels[level].Iter() + + current.IterAllLevelsAndSublevels(func(iter manifest.LevelIterator, level, _ int) { for m := iter.SeekGE(d.cmp, exciseSpan.Start); m != nil && d.cmp(m.Smallest.UserKey, exciseSpan.End) < 0; m = iter.Next() { _, err := d.excise(exciseSpan.UserKeyBounds(), m, ve, level) if err != nil { - d.mu.Lock() - d.mu.versions.logUnlock() - d.mu.Unlock() - return fmt.Sprintf("error when excising %s: %s", m.FileNum, err.Error()) + td.Fatalf(t, "error when excising %s: %s", m.FileNum, err.Error()) } } - } + }) + d.mu.Lock() d.mu.versions.logUnlock() d.mu.Unlock() diff --git a/internal/manifest/version.go b/internal/manifest/version.go index 755f129f02..76d0d48b96 100644 --- a/internal/manifest/version.go +++ b/internal/manifest/version.go @@ -1489,6 +1489,17 @@ func (v *Version) Overlaps(level int, bounds base.UserKeyBounds) LevelSlice { return overlaps(v.Levels[level].Iter(), v.cmp.Compare, bounds) } +// IterAllLevelsAndSublevels calls fn with an iterator for each L0 sublevel +// (from top to bottom), then once for each level below L0. +func (v *Version) IterAllLevelsAndSublevels(fn func(it LevelIterator, level int, sublevel int)) { + for sublevel := len(v.L0SublevelFiles) - 1; sublevel >= 0; sublevel-- { + fn(v.L0SublevelFiles[sublevel].Iter(), 0, sublevel) + } + for level := 1; level < NumLevels; level++ { + fn(v.Levels[level].Iter(), level, invalidSublevel) + } +} + // CheckOrdering checks that the files are consistent with respect to // increasing file numbers (for level 0 files) and increasing and non- // overlapping internal key ranges (for level non-0 files).