From 19ecddac8bef358b15a90f6a0481ca5b93840459 Mon Sep 17 00:00:00 2001 From: sumeerbhola Date: Wed, 5 May 2021 15:11:29 -0400 Subject: [PATCH] db: add IteratorStats, for counting the work done in Iterator The calls to internalIterator are tracked in Iterator since we use both mergingIter and getIter in that role, and we probably don't need these stats for background work (compactions) involving mergingIter. Informs https://github.com/cockroachdb/cockroach/issues/59069 Intended to unblock https://github.com/cockroachdb/cockroach/pull/64503 --- iterator.go | 84 ++++++++++++++++++++++++++- iterator_test.go | 4 +- testdata/iterator | 142 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+), 2 deletions(-) diff --git a/iterator.go b/iterator.go index b60c352e3f..6bfa85eb9c 100644 --- a/iterator.go +++ b/iterator.go @@ -15,6 +15,7 @@ import ( "github.com/cockroachdb/pebble/internal/fastrand" "github.com/cockroachdb/pebble/internal/invariants" "github.com/cockroachdb/pebble/internal/manifest" + "github.com/cockroachdb/redact" ) // iterPos describes the state of the internal iterator, in terms of whether it is @@ -49,7 +50,8 @@ const readBytesPeriod uint64 = 1 << 16 var errReversePrefixIteration = errors.New("pebble: unsupported reverse prefix iteration") -// IteratorMetrics holds per-iterator metrics. +// IteratorMetrics holds per-iterator metrics. These do not change over the +// lifetime of the iterator. type IteratorMetrics struct { // The read amplification experienced by this iterator. This is the sum of // the memtables, the L0 sublevels and the non-empty Ln levels. Higher read @@ -58,6 +60,32 @@ type IteratorMetrics struct { ReadAmp int } +// IteratorStatsKind describes the two kind of iterator stats. +type IteratorStatsKind int8 + +const ( + // InterfaceCall represents calls to Iterator. + InterfaceCall IteratorStatsKind = iota + // InternalIterCall represents calls by Iterator to its internalIterator. + InternalIterCall + // NumStatsKind is the number of kinds, and is used for array sizing. + NumStatsKind +) + +// IteratorStats contains iteration stats. +type IteratorStats struct { + // ForwardSeekCount includes SeekGE, SeekPrefixGE, First. + ForwardSeekCount [NumStatsKind]int + // ReverseSeek includes SeekLT, Last. + ReverseSeekCount [NumStatsKind]int + // ForwardStepCount includes Next. + ForwardStepCount [NumStatsKind]int + // ReverseStepCount includes Prev. + ReverseStepCount [NumStatsKind]int +} + +var _ redact.SafeFormatter = &IteratorStats{} + // Iterator iterates over a DB's key/value pairs in key order. // // An iterator must be closed after use, but it is not necessary to read an @@ -101,6 +129,7 @@ type Iterator struct { getIterAlloc *getIterAlloc prefixOrFullSeekKey []byte readSampling readSampling + stats IteratorStats // Following fields are only used in Clone. // Non-nil if this Iterator includes a Batch. @@ -257,6 +286,7 @@ func (i *Iterator) nextUserKey() { } for { i.iterKey, i.iterValue = i.iter.Next() + i.stats.ForwardStepCount[InternalIterCall]++ if done || i.iterKey == nil { break } @@ -412,6 +442,7 @@ func (i *Iterator) findPrevEntry(limit []byte) { i.iterValidityState = IterExhausted valueMerger = nil i.iterKey, i.iterValue = i.iter.Prev() + i.stats.ReverseStepCount[InternalIterCall]++ // Compare with the limit. We could optimize by only checking when // we step to the previous user key, but detecting that requires a // comparison too. Note that this position may already passed a @@ -439,6 +470,7 @@ func (i *Iterator) findPrevEntry(limit []byte) { i.value = i.valueBuf i.iterValidityState = IterValid i.iterKey, i.iterValue = i.iter.Prev() + i.stats.ReverseStepCount[InternalIterCall]++ valueMerger = nil continue @@ -468,6 +500,7 @@ func (i *Iterator) findPrevEntry(limit []byte) { } } i.iterKey, i.iterValue = i.iter.Prev() + i.stats.ReverseStepCount[InternalIterCall]++ continue default: @@ -501,6 +534,7 @@ func (i *Iterator) prevUserKey() { } for { i.iterKey, i.iterValue = i.iter.Prev() + i.stats.ReverseStepCount[InternalIterCall]++ if i.iterKey == nil { break } @@ -519,6 +553,7 @@ func (i *Iterator) mergeNext(key InternalKey, valueMerger ValueMerger) { // Loop looking for older values for this key and merging them. for { i.iterKey, i.iterValue = i.iter.Next() + i.stats.ForwardStepCount[InternalIterCall]++ if i.iterKey == nil { i.pos = iterPosNext return @@ -572,6 +607,7 @@ func (i *Iterator) SeekGEWithLimit(key []byte, limit []byte) IterValidityState { i.lastPositioningOp = unknownLastPositionOp i.err = nil // clear cached iteration error i.hasPrefix = false + i.stats.ForwardSeekCount[InterfaceCall]++ if lowerBound := i.opts.GetLowerBound(); lowerBound != nil && i.cmp(key, lowerBound) < 0 { key = lowerBound } else if upperBound := i.opts.GetUpperBound(); upperBound != nil && i.cmp(key, upperBound) > 0 { @@ -606,6 +642,7 @@ func (i *Iterator) SeekGEWithLimit(key []byte, limit []byte) IterValidityState { } if seekInternalIter { i.iterKey, i.iterValue = i.iter.SeekGE(key) + i.stats.ForwardSeekCount[InternalIterCall]++ } i.findNextEntry(limit) i.maybeSampleRead() @@ -667,6 +704,7 @@ func (i *Iterator) SeekPrefixGE(key []byte) bool { // iterator position. i.lastPositioningOp = unknownLastPositionOp i.err = nil // clear cached iteration error + i.stats.ForwardSeekCount[InterfaceCall]++ if i.split == nil { panic("pebble: split must be provided for SeekPrefixGE") @@ -728,6 +766,7 @@ func (i *Iterator) SeekPrefixGE(key []byte) bool { } i.iterKey, i.iterValue = i.iter.SeekPrefixGE(i.prefixOrFullSeekKey, key, trySeekUsingNext) + i.stats.ForwardSeekCount[InternalIterCall]++ i.findNextEntry(nil) i.maybeSampleRead() if i.Error() == nil { @@ -761,6 +800,7 @@ func (i *Iterator) SeekLTWithLimit(key []byte, limit []byte) IterValidityState { i.lastPositioningOp = unknownLastPositionOp i.err = nil // clear cached iteration error i.hasPrefix = false + i.stats.ReverseSeekCount[InterfaceCall]++ if upperBound := i.opts.GetUpperBound(); upperBound != nil && i.cmp(key, upperBound) > 0 { key = upperBound } else if lowerBound := i.opts.GetLowerBound(); lowerBound != nil && i.cmp(key, lowerBound) < 0 { @@ -797,6 +837,7 @@ func (i *Iterator) SeekLTWithLimit(key []byte, limit []byte) IterValidityState { } if seekInternalIter { i.iterKey, i.iterValue = i.iter.SeekLT(key) + i.stats.ReverseSeekCount[InternalIterCall]++ } i.findPrevEntry(limit) i.maybeSampleRead() @@ -814,10 +855,13 @@ func (i *Iterator) First() bool { i.err = nil // clear cached iteration error i.hasPrefix = false i.lastPositioningOp = unknownLastPositionOp + i.stats.ForwardSeekCount[InterfaceCall]++ if lowerBound := i.opts.GetLowerBound(); lowerBound != nil { i.iterKey, i.iterValue = i.iter.SeekGE(lowerBound) + i.stats.ForwardSeekCount[InternalIterCall]++ } else { i.iterKey, i.iterValue = i.iter.First() + i.stats.ForwardSeekCount[InternalIterCall]++ } i.findNextEntry(nil) i.maybeSampleRead() @@ -830,10 +874,13 @@ func (i *Iterator) Last() bool { i.err = nil // clear cached iteration error i.hasPrefix = false i.lastPositioningOp = unknownLastPositionOp + i.stats.ReverseSeekCount[InterfaceCall]++ if upperBound := i.opts.GetUpperBound(); upperBound != nil { i.iterKey, i.iterValue = i.iter.SeekLT(upperBound) + i.stats.ReverseSeekCount[InternalIterCall]++ } else { i.iterKey, i.iterValue = i.iter.Last() + i.stats.ReverseSeekCount[InternalIterCall]++ } i.findPrevEntry(nil) i.maybeSampleRead() @@ -848,6 +895,7 @@ func (i *Iterator) Next() bool { // NextWithLimit ... func (i *Iterator) NextWithLimit(limit []byte) IterValidityState { + i.stats.ForwardStepCount[InterfaceCall]++ if limit != nil && i.hasPrefix { i.err = errors.New("cannot use limit with prefix iteration") i.iterValidityState = IterExhausted @@ -875,8 +923,10 @@ func (i *Iterator) NextWithLimit(limit []byte) IterValidityState { // the first key. if lowerBound := i.opts.GetLowerBound(); lowerBound != nil { i.iterKey, i.iterValue = i.iter.SeekGE(lowerBound) + i.stats.ForwardSeekCount[InternalIterCall]++ } else { i.iterKey, i.iterValue = i.iter.First() + i.stats.ForwardSeekCount[InternalIterCall]++ } case iterPosCurReversePaused: // Switching directions. @@ -899,8 +949,10 @@ func (i *Iterator) NextWithLimit(limit []byte) IterValidityState { // the first key. if lowerBound := i.opts.GetLowerBound(); lowerBound != nil { i.iterKey, i.iterValue = i.iter.SeekGE(lowerBound) + i.stats.ForwardSeekCount[InternalIterCall]++ } else { i.iterKey, i.iterValue = i.iter.First() + i.stats.ForwardSeekCount[InternalIterCall]++ } } else { i.nextUserKey() @@ -922,6 +974,7 @@ func (i *Iterator) Prev() bool { // PrevWithLimit ... func (i *Iterator) PrevWithLimit(limit []byte) IterValidityState { + i.stats.ReverseStepCount[InterfaceCall]++ if i.err != nil { return i.iterValidityState } @@ -958,8 +1011,10 @@ func (i *Iterator) PrevWithLimit(limit []byte) IterValidityState { // the last key. if upperBound := i.opts.GetUpperBound(); upperBound != nil { i.iterKey, i.iterValue = i.iter.SeekLT(upperBound) + i.stats.ReverseSeekCount[InternalIterCall]++ } else { i.iterKey, i.iterValue = i.iter.Last() + i.stats.ReverseSeekCount[InternalIterCall]++ } } else { i.prevUserKey() @@ -1115,6 +1170,16 @@ func (i *Iterator) Metrics() IteratorMetrics { return m } +// ResetStats resets the stats to 0. +func (i *Iterator) ResetStats() { + i.stats = IteratorStats{} +} + +// Stats returns the current stats. +func (i *Iterator) Stats() IteratorStats { + return i.stats +} + // Clone creates a new Iterator over the same underlying data, i.e., over the // same {batch, memtables, sstables}). It starts with the same IterOptions but // is not positioned. Note that IterOptions is not deep-copied, so the @@ -1161,3 +1226,20 @@ func (i *Iterator) Clone() (*Iterator, error) { } return finishInitializingIter(buf), nil } + +func (stats *IteratorStats) String() string { + return redact.StringWithoutMarkers(stats) +} + +// SafeFormat implements the redact.SafeFormatter interface. +func (stats *IteratorStats) SafeFormat(s redact.SafePrinter, verb rune) { + for i := range stats.ForwardStepCount { + switch IteratorStatsKind(i) { + case InterfaceCall: s.SafeString("(interface (dir, seek, step): ") + case InternalIterCall: s.SafeString(", (internal (dir, seek, step): ") + } + s.Printf("(fwd, %d, %d), (rev, %d, %d))", + redact.Safe(stats.ForwardSeekCount[i]), redact.Safe(stats.ForwardStepCount[i]), + redact.Safe(stats.ReverseSeekCount[i]), redact.Safe(stats.ReverseStepCount[i])) + } +} diff --git a/iterator_test.go b/iterator_test.go index 797ac38f5d..3a4616d7e2 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -473,7 +473,9 @@ func TestIterator(t *testing.T) { } iter := newIter(uint64(seqNum), opts) - return runIterCmd(d, iter, true) + iterOutput := runIterCmd(d, iter, true) + stats := iter.Stats() + return fmt.Sprintf("%sstats: %s\n", iterOutput, stats.String()) default: return fmt.Sprintf("unknown command: %s", d.Cmd) diff --git a/testdata/iterator b/testdata/iterator index c268768beb..f9f331f12d 100644 --- a/testdata/iterator +++ b/testdata/iterator @@ -10,16 +10,19 @@ prev a:b . a:b +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 1, 1)) iter seq=2 seek-ge b ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 seek-lt a ---- . +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)) define @@ -35,6 +38,7 @@ prev a:b . a:b +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 1, 1)) iter seq=3 seek-ge a @@ -44,6 +48,7 @@ prev a:c . a:c +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 1, 2)) iter seq=2 seek-prefix-ge a @@ -55,6 +60,7 @@ a:b . err=pebble: unsupported reverse prefix iteration err=pebble: unsupported reverse prefix iteration +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=3 seek-prefix-ge a @@ -62,6 +68,7 @@ next ---- a:c . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define @@ -73,6 +80,7 @@ iter seq=3 seek-ge a ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=2 seek-ge 1 @@ -80,11 +88,13 @@ next ---- a:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=3 seek-lt b ---- . +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 2)) iter seq=2 seek-lt b @@ -94,16 +104,19 @@ next a:b . a:b +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 1)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 1)) iter seq=3 seek-prefix-ge a ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=2 seek-prefix-ge 1 ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) define a.DEL.2: @@ -117,31 +130,37 @@ next ---- b:c . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 3), (rev, 0, 0)) iter seq=3 seek-ge a ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=2 seek-ge a ---- a:b +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=4 seek-prefix-ge a ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=3 seek-prefix-ge a ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=2 seek-prefix-ge a ---- a:b +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 seek-prefix-ge a @@ -149,6 +168,7 @@ seek-prefix-ge b ---- a:b . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)) define a.DEL.3: @@ -166,6 +186,7 @@ seek-prefix-ge c . . c:d +stats: (interface (dir, seek, step): (fwd, 3, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 3, 4), (rev, 0, 0)) iter seq=3 seek-prefix-ge a @@ -175,6 +196,7 @@ seek-prefix-ge c a:b b:c . +stats: (interface (dir, seek, step): (fwd, 3, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 3, 0), (rev, 0, 0)) define a.SET.1:a @@ -192,6 +214,7 @@ a:a b:b c:c . +stats: (interface (dir, seek, step): (fwd, 1, 3), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 3), (rev, 0, 0)) iter seq=4 seek-ge b @@ -199,16 +222,19 @@ next ---- b:b c:c +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=4 seek-ge c ---- c:c +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=4 seek-lt a ---- . +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)) iter seq=4 seek-lt b @@ -218,6 +244,7 @@ next a:a . a:a +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 1)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 1)) iter seq=4 seek-lt c @@ -229,6 +256,7 @@ b:b a:a . a:a +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 2)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 2)) iter seq=4 @@ -243,6 +271,7 @@ b:b a:a . a:a +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 3)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 3)) iter seq=4 seek-prefix-ge a @@ -250,6 +279,7 @@ next ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=4 seek-prefix-ge b @@ -257,6 +287,7 @@ next ---- b:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=4 @@ -265,12 +296,14 @@ next ---- c:c . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=4 seek-prefix-ge d ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=4 seek-prefix-ge a @@ -280,6 +313,7 @@ seek-prefix-ge b a:a c:c b:b +stats: (interface (dir, seek, step): (fwd, 3, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 3, 0), (rev, 0, 0)) define a.SET.b2:b @@ -294,16 +328,19 @@ prev a:b . a:b +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 1, 1)) iter seq=2 seek-ge b ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 seek-lt a ---- . +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)) iter seq=2 seek-lt b @@ -313,6 +350,7 @@ next a:b . a:b +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 1)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 1)) iter seq=2 seek-lt c @@ -322,6 +360,7 @@ next a:b . a:b +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 1)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 1)) iter seq=2 seek-prefix-ge a @@ -329,11 +368,13 @@ next ---- a:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=2 seek-prefix-ge b ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) define @@ -349,6 +390,7 @@ next ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=5 seek-prefix-ge a @@ -356,11 +398,13 @@ next ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=5 seek-prefix-ge aa ---- aa:aa +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=5 seek-prefix-ge aa @@ -368,6 +412,7 @@ next ---- aa:aa . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=5 seek-prefix-ge aa @@ -375,6 +420,7 @@ next ---- aa:aa . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=5 seek-prefix-ge aaa @@ -382,11 +428,13 @@ next ---- aaa:aaa . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=5 seek-prefix-ge aaa ---- aaa:aaa +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=5 seek-prefix-ge b @@ -394,6 +442,7 @@ next ---- b:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=5 seek-prefix-ge aa @@ -409,6 +458,7 @@ aaa:aaa aa:aa a:a . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 1, 4)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 4)) iter seq=5 seek-prefix-ge aa @@ -424,6 +474,7 @@ aa:aa aaa:aaa b:b . +stats: (interface (dir, seek, step): (fwd, 2, 4), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 2, 4), (rev, 0, 0)) iter seq=5 seek-prefix-ge aaa @@ -437,6 +488,7 @@ aa:aa aaa:aaa b:b . +stats: (interface (dir, seek, step): (fwd, 2, 3), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 2, 3), (rev, 0, 0)) iter seq=5 seek-prefix-ge aaa @@ -448,6 +500,7 @@ aaa:aaa aaa:aaa b:b . +stats: (interface (dir, seek, step): (fwd, 2, 2), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 2, 2), (rev, 0, 0)) iter seq=5 seek-prefix-ge aaa @@ -463,6 +516,7 @@ aa:aa aaa:aaa b:b . +stats: (interface (dir, seek, step): (fwd, 1, 4), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 2, 4), (rev, 1, 1)) iter seq=5 @@ -475,6 +529,7 @@ aaa:aaa aaa:aaa b:b . +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 1, 3), (rev, 1, 1)) iter seq=4 seek-prefix-ge a @@ -486,6 +541,7 @@ a:a aa:aa aaa:aaa . +stats: (interface (dir, seek, step): (fwd, 4, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 4, 0), (rev, 0, 0)) iter seq=3 seek-prefix-ge aaa @@ -499,6 +555,7 @@ seek-prefix-ge aaa a:a aa:aa . +stats: (interface (dir, seek, step): (fwd, 5, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 5, 0), (rev, 0, 0)) define bb.DEL.2: @@ -510,6 +567,7 @@ iter seq=4 seek-prefix-ge bb ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) # NB: RANGEDEL entries are ignored. @@ -536,6 +594,7 @@ a:bcd b:ab . b:ab +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 5), (rev, 1, 2)) iter seq=3 seek-ge a @@ -543,6 +602,7 @@ next ---- a:bc b:ab +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 4), (rev, 0, 0)) iter seq=2 seek-ge a @@ -550,6 +610,7 @@ next ---- a:b b:a +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=4 seek-lt c @@ -561,6 +622,7 @@ b:ab a:bcd . a:bcd +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 2)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 1, 5)) iter seq=3 seek-lt c @@ -568,6 +630,7 @@ prev ---- b:ab a:bc +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 1)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 4)) iter seq=2 seek-lt c @@ -575,6 +638,7 @@ prev ---- b:a a:b +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 1)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 2)) iter seq=4 seek-ge a @@ -586,6 +650,7 @@ a:bcd b:ab a:bcd b:ab +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 10), (rev, 1, 5)) iter seq=3 seek-ge a @@ -597,6 +662,7 @@ a:bc b:ab a:bc b:ab +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 8), (rev, 1, 4)) iter seq=2 seek-ge a @@ -608,6 +674,7 @@ a:b b:a a:b b:a +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 4), (rev, 1, 2)) iter seq=4 seek-lt c @@ -619,6 +686,7 @@ b:ab a:bcd b:ab a:bcd +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 2)), (internal (dir, seek, step): (fwd, 1, 5), (rev, 2, 10)) iter seq=3 seek-lt c @@ -630,6 +698,7 @@ b:ab a:bc b:ab a:bc +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 2)), (internal (dir, seek, step): (fwd, 1, 4), (rev, 2, 8)) iter seq=2 seek-lt c @@ -641,6 +710,7 @@ b:a a:b b:a a:b +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 2)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 2, 4)) iter seq=3 seek-prefix-ge a @@ -648,6 +718,7 @@ next ---- a:bc . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=2 seek-prefix-ge a @@ -655,6 +726,7 @@ next ---- a:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=4 seek-prefix-ge a @@ -662,6 +734,7 @@ next ---- a:bcd . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 3), (rev, 0, 0)) iter seq=2 seek-prefix-ge a @@ -669,6 +742,7 @@ next ---- a:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=3 seek-prefix-ge a @@ -676,21 +750,25 @@ next ---- a:bc . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=3 seek-prefix-ge c ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=3 seek-prefix-ge 1 ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=3 seek-prefix-ge a ---- a:bc +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) # NB: RANGEDEL entries are ignored. @@ -719,6 +797,7 @@ next a:bc . . +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 4), (rev, 0, 0)) iter seq=2 seek-prefix-ge a @@ -728,6 +807,7 @@ next a:b . . +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=4 seek-prefix-ge a @@ -735,6 +815,7 @@ next ---- a:bcd . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 3), (rev, 0, 0)) iter seq=2 seek-prefix-ge a @@ -742,6 +823,7 @@ next ---- a:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=3 seek-prefix-ge aa @@ -749,11 +831,13 @@ next ---- aa:ab . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) iter seq=4 seek-prefix-ge aa ---- aa:ab +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define a.SET.1:a @@ -770,6 +854,7 @@ prev a:a a:a . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 lower=b seek-ge a @@ -779,6 +864,7 @@ prev b:b b:b . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 lower=c seek-ge a @@ -788,6 +874,7 @@ prev c:c c:c . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 lower=d seek-ge a @@ -797,6 +884,7 @@ prev d:d d:d . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 lower=e seek-ge a @@ -804,6 +892,7 @@ first ---- . . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)) iter seq=2 upper=d seek-lt d @@ -813,6 +902,7 @@ next c:c c:c . +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 0, 2), (rev, 2, 2)) iter seq=2 upper=c seek-lt d @@ -822,6 +912,7 @@ next b:b b:b . +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 0, 2), (rev, 2, 2)) iter seq=2 upper=b seek-lt d @@ -831,6 +922,7 @@ next a:a a:a . +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 2, 2)) iter seq=2 upper=a seek-lt d @@ -838,6 +930,7 @@ last ---- . . +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 2, 0)) iter seq=2 lower=b upper=c seek-ge a @@ -845,6 +938,7 @@ next ---- b:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=2 set-bounds lower=a @@ -856,6 +950,7 @@ prev a:a a:a . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 set-bounds lower=b @@ -867,6 +962,7 @@ prev b:b b:b . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 set-bounds lower=c @@ -878,6 +974,7 @@ prev c:c c:c . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 set-bounds lower=d @@ -889,6 +986,7 @@ prev d:d d:d . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 set-bounds lower=e @@ -898,6 +996,7 @@ first . . . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)) iter seq=2 set-bounds upper=d @@ -909,6 +1008,7 @@ next c:c c:c . +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 0, 2), (rev, 2, 2)) iter seq=2 set-bounds upper=c @@ -920,6 +1020,7 @@ next b:b b:b . +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 0, 2), (rev, 2, 2)) iter seq=2 set-bounds upper=b @@ -931,6 +1032,7 @@ next a:a a:a . +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 2, 2)) iter seq=2 set-bounds upper=a @@ -940,6 +1042,7 @@ last . . . +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 2, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 2, 0)) iter seq=2 set-bounds lower=a @@ -951,6 +1054,7 @@ next c:c d:d . +stats: (interface (dir, seek, step): (fwd, 0, 2), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 0, 3), (rev, 1, 1)) iter seq=2 set-bounds lower=b upper=c @@ -960,6 +1064,7 @@ next . b:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=2 set-bounds lower=b @@ -971,6 +1076,7 @@ seek-ge a b:b . b:b +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 0)) iter seq=2 seek-ge a @@ -978,6 +1084,7 @@ set-bounds upper=e ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 set-bounds lower=b @@ -987,6 +1094,7 @@ set-bounds upper=e . b:b . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 set-bounds lower=b @@ -994,6 +1102,7 @@ first ---- . b:b +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 set-bounds upper=b @@ -1001,6 +1110,7 @@ first ---- . a:a +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 set-bounds lower=b @@ -1008,6 +1118,7 @@ last ---- . d:d +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 1)) iter seq=2 set-bounds upper=b @@ -1015,6 +1126,7 @@ last ---- . a:a +stats: (interface (dir, seek, step): (fwd, 0, 0), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 1, 1)) # The prev call after "set-bounds upper=c" will assume that the iterator # is exhausted due to having stepped up to c. Which means prev should step @@ -1029,6 +1141,7 @@ d:d . . b:b +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 1)), (internal (dir, seek, step): (fwd, 0, 2), (rev, 2, 2)) # The next call after "set-bounds lower=b" will assume that the iterator # is exhausted due to having stepped below b. Which means next should step @@ -1043,6 +1156,7 @@ a:a . . b:b +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 set-bounds lower=b @@ -1052,6 +1166,7 @@ next . b:b c:c +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 1, 1)) iter seq=2 set-bounds upper=d @@ -1061,6 +1176,7 @@ prev . c:c b:b +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 2)) define a.SET.1:a @@ -1077,12 +1193,14 @@ prev a:a a:a . +stats: (interface (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 2, 0), (rev, 0, 1)) iter seq=2 lower=aa seek-prefix-ge a ---- err=pebble: SeekPrefixGE supplied with key outside of lower bound +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 0, 0), (rev, 0, 0)) iter seq=2 lower=a upper=aa seek-prefix-ge a @@ -1090,6 +1208,7 @@ next ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=2 lower=a upper=aaa seek-prefix-ge a @@ -1097,6 +1216,7 @@ next ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=2 lower=a upper=b seek-prefix-ge a @@ -1104,6 +1224,7 @@ next ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=2 lower=a upper=c seek-prefix-ge a @@ -1111,11 +1232,13 @@ next ---- a:a . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) iter seq=2 lower=a upper=aaa seek-prefix-ge aa ---- aa:aa +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) iter seq=2 lower=a upper=aaa seek-prefix-ge aa @@ -1123,6 +1246,7 @@ next ---- aa:aa . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) # NB: RANGEDEL entries are ignored. define @@ -1141,6 +1265,7 @@ next a:a b:b . +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define a.SINGLEDEL.1: @@ -1150,6 +1275,7 @@ iter seq=2 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)) define a.SINGLEDEL.2: @@ -1160,6 +1286,7 @@ iter seq=3 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define a.SINGLEDEL.2: @@ -1170,6 +1297,7 @@ iter seq=3 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define a.SINGLEDEL.2: @@ -1180,6 +1308,7 @@ iter seq=3 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define a.SINGLEDEL.2: @@ -1190,6 +1319,7 @@ iter seq=3 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define a.SET.2:b @@ -1202,6 +1332,7 @@ next ---- a:b . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) define a.SINGLEDEL.2: @@ -1215,6 +1346,7 @@ next ---- b:c . +stats: (interface (dir, seek, step): (fwd, 1, 1), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 3), (rev, 0, 0)) define a.SINGLEDEL.3: @@ -1226,6 +1358,7 @@ iter first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)) define a.SINGLEDEL.3: @@ -1237,6 +1370,7 @@ iter seq=4 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 3), (rev, 0, 0)) define a.SINGLEDEL.4: @@ -1249,6 +1383,7 @@ iter seq=5 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 4), (rev, 0, 0)) define a.SINGLEDEL.4: @@ -1261,6 +1396,7 @@ iter seq=5 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 4), (rev, 0, 0)) define a.SINGLEDEL.4: @@ -1273,6 +1409,7 @@ iter seq=5 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 4), (rev, 0, 0)) define a.SINGLEDEL.3: @@ -1284,6 +1421,7 @@ iter seq=4 first ---- . +stats: (interface (dir, seek, step): (fwd, 1, 0), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 1, 2), (rev, 0, 0)) # Exercise iteration with limits, when there are no deletes. define @@ -1325,6 +1463,7 @@ a:a valid . exhausted . at-limit a:a valid +stats: (interface (dir, seek, step): (fwd, 1, 6), (rev, 1, 7)), (internal (dir, seek, step): (fwd, 3, 3), (rev, 1, 6)) # Exercise iteration with limits when we have deletes. @@ -1371,6 +1510,7 @@ d:d valid . exhausted d:d valid . exhausted +stats: (interface (dir, seek, step): (fwd, 1, 10), (rev, 0, 5)), (internal (dir, seek, step): (fwd, 3, 13), (rev, 1, 8)) iter seq=4 seek-ge-limit b d @@ -1382,6 +1522,7 @@ next-limit e . at-limit . at-limit d:d valid +stats: (interface (dir, seek, step): (fwd, 1, 2), (rev, 0, 1)), (internal (dir, seek, step): (fwd, 1, 9), (rev, 0, 5)) iter seq=4 seek-lt-limit d c @@ -1397,3 +1538,4 @@ next-limit b a:a valid . exhausted a:a valid +stats: (interface (dir, seek, step): (fwd, 0, 1), (rev, 1, 4)), (internal (dir, seek, step): (fwd, 1, 0), (rev, 1, 5))