@@ -14,6 +14,7 @@ import (
1414 "github.com/cockroachdb/pebble/internal/base"
1515 "github.com/cockroachdb/pebble/internal/keyspan"
1616 "github.com/cockroachdb/pebble/internal/manifest"
17+ "github.com/cockroachdb/pebble/internal/rangedel"
1718)
1819
1920// This file implements DB.CheckLevels() which checks that every entry in the
@@ -47,11 +48,10 @@ import (
4748
4849// The per-level structure used by simpleMergingIter.
4950type simpleMergingIterLevel struct {
50- iter internalIterator
51- rangeDelIter keyspan.FragmentIterator
52-
53- iterKV * base.InternalKV
54- tombstone * keyspan.Span
51+ iter internalIterator
52+ getTombstone func () * keyspan.Span
53+ iterKV * base.InternalKV
54+ iterTombstone * keyspan.Span
5555}
5656
5757type simpleMergingIter struct {
@@ -102,22 +102,6 @@ func (m *simpleMergingIter) init(
102102 if m .heap .len () == 0 {
103103 return
104104 }
105- m .positionRangeDels ()
106- }
107-
108- // Positions all the rangedel iterators at or past the current top of the
109- // heap, using SeekGE().
110- func (m * simpleMergingIter ) positionRangeDels () {
111- item := & m .heap .items [0 ]
112- for i := range m .levels {
113- l := & m .levels [i ]
114- if l .rangeDelIter == nil {
115- continue
116- }
117- t , err := l .rangeDelIter .SeekGE (item .key .UserKey )
118- m .err = firstError (m .err , err )
119- l .tombstone = t
120- }
121105}
122106
123107// Returns true if not yet done.
@@ -128,7 +112,12 @@ func (m *simpleMergingIter) step() bool {
128112 item := & m .heap .items [0 ]
129113 l := & m .levels [item .index ]
130114 // Sentinels are not relevant for this point checking.
131- if ! item .key .IsExclusiveSentinel () && item .key .Visible (m .snapshot , base .InternalKeySeqNumMax ) {
115+ if item .key .IsExclusiveSentinel () {
116+ l .iterTombstone = nil
117+ if item .key .Kind () != base .InternalKeyKindSpanEnd {
118+ l .iterTombstone = l .getTombstone ()
119+ }
120+ } else if item .key .Visible (m .snapshot , base .InternalKeySeqNumMax ) {
132121 // This is a visible point key.
133122 if ! m .handleVisiblePoint (item , l ) {
134123 return false
@@ -187,7 +176,6 @@ func (m *simpleMergingIter) step() bool {
187176 }
188177 return false
189178 }
190- m .positionRangeDels ()
191179 return true
192180}
193181
@@ -269,12 +257,12 @@ func (m *simpleMergingIter) handleVisiblePoint(
269257 // iterators must be positioned at a key > item.key.
270258 for level := item .index + 1 ; level < len (m .levels ); level ++ {
271259 lvl := & m .levels [level ]
272- if lvl .rangeDelIter == nil || lvl . tombstone .Empty () {
260+ if lvl .iterTombstone .Empty () {
273261 continue
274262 }
275- if lvl .tombstone .Contains (m .heap .cmp , item .key .UserKey ) && lvl .tombstone .CoversAt (m .snapshot , item .key .SeqNum ()) {
263+ if lvl .iterTombstone .Contains (m .heap .cmp , item .key .UserKey ) && lvl .iterTombstone .CoversAt (m .snapshot , item .key .SeqNum ()) {
276264 m .err = errors .Errorf ("tombstone %s in %s deletes key %s in %s" ,
277- lvl .tombstone .Pretty (m .formatKey ), lvl .iter , item .key .Pretty (m .formatKey ),
265+ lvl .iterTombstone .Pretty (m .formatKey ), lvl .iter , item .key .Pretty (m .formatKey ),
278266 l .iter )
279267 return false
280268 }
@@ -593,20 +581,15 @@ func checkLevelsInternal(c *checkConfig) (err error) {
593581 err = firstError (err , l .iter .Close ())
594582 l .iter = nil
595583 }
596- if l .rangeDelIter != nil {
597- err = firstError (err , l .rangeDelIter .Close ())
598- l .rangeDelIter = nil
599- }
600584 }
601585 }()
602586
603587 memtables := c .readState .memtables
604588 for i := len (memtables ) - 1 ; i >= 0 ; i -- {
605589 mem := memtables [i ]
606- mlevels = append (mlevels , simpleMergingIterLevel {
607- iter : mem .newIter (nil ),
608- rangeDelIter : mem .newRangeDelIter (nil ),
609- })
590+ var smil simpleMergingIterLevel
591+ smil .iter , smil .getTombstone = rangedel .Interleave (c .comparer , mem .newIter (nil ), mem .newRangeDelIter (nil ))
592+ mlevels = append (mlevels , smil )
610593 }
611594
612595 current := c .readState .current
@@ -636,8 +619,9 @@ func checkLevelsInternal(c *checkConfig) (err error) {
636619 li := & levelIter {}
637620 li .init (context .Background (), iterOpts , c .comparer , c .newIters , manifestIter ,
638621 manifest .L0Sublevel (sublevel ), internalIterOpts {})
639- li .initRangeDel ( & mlevelAlloc [ 0 ]. rangeDelIter )
622+ li .interleaveRangeDeletions = true
640623 mlevelAlloc [0 ].iter = li
624+ mlevelAlloc [0 ].getTombstone = li .getTombstone
641625 mlevelAlloc = mlevelAlloc [1 :]
642626 }
643627 for level := 1 ; level < len (current .Levels ); level ++ {
@@ -649,8 +633,9 @@ func checkLevelsInternal(c *checkConfig) (err error) {
649633 li := & levelIter {}
650634 li .init (context .Background (), iterOpts , c .comparer , c .newIters ,
651635 current .Levels [level ].Iter (), manifest .Level (level ), internalIterOpts {})
652- li .initRangeDel ( & mlevelAlloc [ 0 ]. rangeDelIter )
636+ li .interleaveRangeDeletions = true
653637 mlevelAlloc [0 ].iter = li
638+ mlevelAlloc [0 ].getTombstone = li .getTombstone
654639 mlevelAlloc = mlevelAlloc [1 :]
655640 }
656641
0 commit comments