# Test case for bug https://github.com/cockroachdb/pebble/v2/issues/2036 Build
# sstable with two-level index, with two data blocks in each lower-level index
# block.
build block-size=1 index-block-size=40 print-layout=true
c@10.SET.10:cAT10
d@7.SET.9:dAT7
e@15.SET.8:eAT15
f@7.SET.5:fAT7
----
index entries:
 d@7: size 53
   c@10: size 29
   d@7: size 27
 g: size 51
   e@15: size 29
   g: size 27

iter
first
next
next
next
----
first: <c@10:10>
 next: <d@7:9>
 next: <e@15:8>
 next: <f@7:5>


# The block property filter matches data block 2 and 4.
iter block-property-filter=(7,8)
first
next
----
first: <d@7:9>
 next: <f@7:5>

# Use the same block property filter, but use seeks to find these entries.
# With the bug the second seek-ge below would step to the second lower-level
# index block and only see the entry in the data block 4.
iter block-property-filter=(7,8)
set-bounds lower=a upper=c
seek-ge a
seek-ge b true
set-bounds lower=c upper=g
seek-ge c
next
next
----
set-bounds lower=a upper=c: .
                 seek-ge a: .
            seek-ge b true: .
set-bounds lower=c upper=g: .
                 seek-ge c: <d@7:9>
                      next: <f@7:5>
                      next: .

# Regression test for #2816
#
# This unit test tests a scenario where the two-level index iterator's position
# could diverge from the currently loaded index block. When taking advantage of
# the monotonic bounds optimization at the two-level index level, the iterator
# would mistakenly seek within the wrong index block.
#
# This allowed the final `seek-ge wc` and `next` to both return wz@8.

build  block-size=1 index-block-size=1 print-layout=true
eu@2.SET.2:eu
wb@2.SET.2:wb
wz@8.SET.8:wzAT8
ye@1.SET.1:yeAT1
----
index entries:
 f: size 26
   f: size 26
 wc: size 27
   wc: size 26
 x: size 26
   x: size 29
 z: size 26
   z: size 29

iter block-property-filter=(8,9)
set-bounds lower=v upper=v
seek-ge wz@8
internal-iter-state
seek-ge wb@2
internal-iter-state
set-bounds lower=v upper=z
internal-iter-state
seek-ge wc
internal-iter-state
next
----
set-bounds lower=v upper=v: .
              seek-ge wz@8: .
| *sstable.twoLevelIterator[github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter]:
|  topLevelIndex.Key() = "x"
|  topLevelIndex.BlockHandleWithProperties() = (Offset: 193, Length: 26, Props: 00020801)
|  topLevelIndex.isDataInvalidated()=false
|  index.Separator() = "x"
|  index.BlockHandleWithProperties() = (Offset: 62, Length: 29, Props: 00020801)
|  index.isDataInvalidated()=false
|  data.isDataInvalidated()=false
|  hideObsoletePoints = false
|  dataBH = (Offset: 62, Length: 29)
|  (boundsCmp,positionedUsingLatestBounds) = (0,true)
|  exhaustedBounds = 1
              seek-ge wb@2: .
| *sstable.twoLevelIterator[github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter]:
|  topLevelIndex.Key() = "wc"
|  topLevelIndex.BlockHandleWithProperties() = (Offset: 161, Length: 27, Props: 00020201)
|  topLevelIndex.isDataInvalidated()=false
|  index iter invalid
|  index.isDataInvalidated()=true
|  data.isDataInvalidated()=true
|  hideObsoletePoints = false
|  dataBH = (Offset: 62, Length: 29)
|  (boundsCmp,positionedUsingLatestBounds) = (0,true)
|  exhaustedBounds = 1
set-bounds lower=v upper=z: .
| *sstable.twoLevelIterator[github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter]:
|  topLevelIndex.Key() = "wc"
|  topLevelIndex.BlockHandleWithProperties() = (Offset: 161, Length: 27, Props: 00020201)
|  topLevelIndex.isDataInvalidated()=false
|  index iter invalid
|  index.isDataInvalidated()=true
|  data.isDataInvalidated()=true
|  hideObsoletePoints = false
|  dataBH = (Offset: 62, Length: 29)
|  (boundsCmp,positionedUsingLatestBounds) = (1,false)
|  exhaustedBounds = 1
                seek-ge wc: <wz@8:8>
| *sstable.twoLevelIterator[github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.IndexIter,github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter,*github.com/cockroachdb/pebble/v2/sstable/rowblk.Iter]:
|  topLevelIndex.Key() = "x"
|  topLevelIndex.BlockHandleWithProperties() = (Offset: 193, Length: 26, Props: 00020801)
|  topLevelIndex.isDataInvalidated()=false
|  index.Separator() = "x"
|  index.BlockHandleWithProperties() = (Offset: 62, Length: 29, Props: 00020801)
|  index.isDataInvalidated()=false
|  data.isDataInvalidated()=false
|  hideObsoletePoints = false
|  dataBH = (Offset: 62, Length: 29)
|  (boundsCmp,positionedUsingLatestBounds) = (0,false)
|  exhaustedBounds = 0
                      next: .
