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: (interface (dir, seek, step): (fwd, 5, 5), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 5, 5), (rev, 0, 0)), (internal-stats: (block-bytes: (total 475B, cached 0B, read-time 0s)), (points: (count 10, key-bytes 50B, value-bytes 50B, tombstoned 0))) # 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: (interface (dir, seek, step): (fwd, 5, 5), (rev, 0, 0)), (internal (dir, seek, step): (fwd, 5, 5), (rev, 0, 0)), (internal-stats: (block-bytes: (total 281B, cached 0B, read-time 0s)), (points: (count 10, key-bytes 50B, value-bytes 50B, tombstoned 0)))