build 1
set b b
set c c
----

build 2
del-range c z
----

# Test that a delete range in a more recent file shadows keys in an
# earlier file.

iter files=(1)
first
next
next
----
b: (b, .)
c: (c, .)
.

iter files=(1)
seek-ge bb
next
----
c: (c, .)
.

iter files=(2, 1) fwd-only
first
next
----
b: (b, .)
.

build 3
set a a
set f f
----

# Test including an even more recent file with point keys overlapping
# the rangedel. Since the point keys are assigned a higher sequence
# number, they should NOT be shadowed by the rangedel.

iter files=(3, 2, 1) fwd-only
first
next
next
next
----
a: (a, .)
b: (b, .)
f: (f, .)
.

# Test including range keys, and merging the range key state across
# files. Range keys should be interleaved.

build 4
range-key-set a c @2 foo
range-key-set c e @3 bar
----

build 5
range-key-del b d
----

iter files=(5, 4, 3, 2, 1) fwd-only
first
next
next
next
next
----
a: (a, [a-b) @2=foo UPDATED)
b: (b, . UPDATED)
d: (., [d-e) @3=bar UPDATED)
f: (f, . UPDATED)
.

# Test including range keys with empty spans and a merge in between. At no point
# should an empty span be returned.

build 6
merge bb ac
----

iter files=(6, 5, 4, 3, 2, 1)
seek-lt c
prev
next
next
----
bb: (ac, .)
b: (b, .)
bb: (ac, .)
d: (., [d-e) @3=bar UPDATED)

iter files=(6, 5, 4, 3, 2, 1)
seek-ge b
next
prev
prev
next
next
next
----
b: (b, .)
bb: (ac, .)
b: (b, .)
a: (a, [a-b) @2=foo UPDATED)
b: (b, . UPDATED)
bb: (ac, .)
d: (., [d-e) @3=bar UPDATED)

# Test range keys that overlap each other with identical state. These
# should be defragmented and exposed as a single range key.

reset
----

build ag
range-key-set a g @5 foo
----

build ek
range-key-set e k @5 foo
----

iter files=(ag, ek) fwd-only
first
next
----
a: (., [a-k) @5=foo UPDATED)
.

# Test range-key masking by creating points, some with suffixes above
# the range key's suffix, some with suffixes below the range key's
# suffix.

build points
set a@4 v
set c@2 v
set d@9 v
set e@5 v
set k@3 v
set p@4 v
----

iter files=(points, ag, ek) mask-suffix=@7 fwd-only
first
next
next
next
next
next
----
a: (., [a-k) @5=foo UPDATED)
d@9: (v, [a-k) @5=foo)
e@5: (v, [a-k) @5=foo)
k@3: (v, . UPDATED)
p@4: (v, .)
.

# Test that 'stacked' range keys (eg, multiple defined over the same keyspan at
# varying suffixes) work  as expected.

build stacked
range-key-set a k @4 bar
range-key-set a k @1 bax
----

iter files=(points, ag, ek, stacked) fwd-only
first
next
----
a: (., [a-k) @5=foo, @4=bar, @1=bax UPDATED)
a@4: (v, [a-k) @5=foo, @4=bar, @1=bax)

# Test mutating the external iterator's options through SetOptions.

iter files=(points, ag, ek) fwd-only
set-options key-types=point
first
next
set-options lower=e upper=p
first
next
----
.
a@4: (v, .)
c@2: (v, .)
.
e@5: (v, .)
k@3: (v, .)

# Test the TrySeekUsingNext optimization that's enabled only for fwd-only
# external iterators. Seed the database with keys like 'a', 'aa', 'aaa', etc so
# that the index block uses a final separator that's beyond all the other live
# keys.

reset
----

build a
set a@3 a@3
set a@1 a@1
----

build aa
set aa@3 aa@3
set aa@1 aa@1
----

build aaa
set aaa@3 aaa@3
set aaa@1 aaa@1
----

build aaaa
set aaaa@3 aaaa@3
set aaaa@1 aaaa@1
----

build aaaaa
set aaaaa@3 aaaaa@3
set aaaaa@1 aaaaa@1
----

# Note the absence of fwd-only. This iterator will not use the TrySeekUsingNext
# optimization.

iter files=(a, aa, aaa, aaaa, aaaaa)
seek-ge a
next
seek-ge aa
next
seek-ge aaa
next
seek-ge aaaa
next
seek-ge aaaaa
next
stats
----
a@3: (a@3, .)
a@1: (a@1, .)
aa@3: (aa@3, .)
aa@1: (aa@1, .)
aaa@3: (aaa@3, .)
aaa@1: (aaa@1, .)
aaaa@3: (aaaa@3, .)
aaaa@1: (aaaa@1, .)
aaaaa@3: (aaaaa@3, .)
aaaaa@1: (aaaaa@1, .)
stats: seeked 5 times (5 internal); stepped 5 times (5 internal); blocks: 0B cached, 475B not cached (read time: 0s); points: 10 (50B keys, 50B values)

# Note the inclusion of fwd-only. This iterator will use the TrySeekUsingNext
# optimization and loads ~half the block-bytes as a result.

iter files=(a, aa, aaa, aaaa, aaaaa) fwd-only
seek-ge a
next
seek-ge aa
next
seek-ge aaa
next
seek-ge aaaa
next
seek-ge aaaaa
next
stats
----
a@3: (a@3, .)
a@1: (a@1, .)
aa@3: (aa@3, .)
aa@1: (aa@1, .)
aaa@3: (aaa@3, .)
aaa@1: (aaa@1, .)
aaaa@3: (aaaa@3, .)
aaaa@1: (aaaa@1, .)
aaaaa@3: (aaaaa@3, .)
aaaaa@1: (aaaaa@1, .)
stats: seeked 5 times (5 internal); stepped 5 times (5 internal); blocks: 0B cached, 281B not cached (read time: 0s); points: 10 (50B keys, 50B values)
