switch 1 ---- ok build ext0 set a 1 set l 2 ---- ingest ext0 ---- lsm ---- 6: 000004:[a#10,SET-l#10,SET] batch set d foo set f bar ---- flush ---- compact a-z ---- ok lsm ---- 6: 000008:[a#0,SET-l#0,SET] switch 2 ---- ok iter first ---- . replicate 1 2 d g ---- replicated 1 shared SSTs lsm ---- 6: 000005:[d#10,SET-f#10,SET] iter first next next ---- d: (foo, .) f: (bar, .) . batch set e bar set f bar2 set g bar3 ---- iter first next next next ---- d: (foo, .) e: (bar, .) f: (bar2, .) g: (bar3, .) compact a-z ---- ok iter first next next next ---- d: (foo, .) e: (bar, .) f: (bar2, .) g: (bar3, .) # Write a new key at f, but don't compact it down. batch set f bar3 ---- switch 1 ---- ok lsm ---- 6: 000008:[a#0,SET-l#0,SET] excise e gg ---- would excise 1 files, use ingest-and-excise to excise. deleted: L6 000008 added: L6 000009:[a#0,1-d#0,1] added: L6 000010:[l#0,1-l#0,1] replicate 2 1 e gg ---- replicated 1 shared SSTs iter first next next next next ---- a: (1, .) d: (foo, .) e: (bar, .) f: (bar3, .) g: (bar3, .) # Range key masking test. Write some masked keys, then replicate before # compacting, then compact, then replicate back. batch set h@3 foobar set i@5 baz range-key-set g j @4 value ---- iter first next next next next next next next ---- a: (1, .) d: (foo, .) e: (bar, .) f: (bar3, .) g: (bar3, [g-j) @4=value UPDATED) h@3: (foobar, [g-j) @4=value) i@5: (baz, [g-j) @4=value) l: (2, . UPDATED) iter mask-filter mask-suffix=@6 first next next next next next next ---- a: (1, .) d: (foo, .) e: (bar, .) f: (bar3, .) g: (bar3, [g-j) @4=value UPDATED) i@5: (baz, [g-j) @4=value) l: (2, . UPDATED) switch 2 ---- ok replicate 1 2 a z ---- replicated 3 shared SSTs iter first next next next next next next next ---- a: (1, .) d: (foo, .) e: (bar, .) f: (bar3, .) g: (bar3, [g-j) @4=value UPDATED) h@3: (foobar, [g-j) @4=value) i@5: (baz, [g-j) @4=value) l: (2, . UPDATED) iter mask-filter mask-suffix=@6 first next next next next next next ---- a: (1, .) d: (foo, .) e: (bar, .) f: (bar3, .) g: (bar3, [g-j) @4=value UPDATED) i@5: (baz, [g-j) @4=value) l: (2, . UPDATED) compact a-z ---- ok replicate 2 1 a z ---- replicated 3 shared SSTs switch 1 ---- ok iter first next next next next next next next next ---- a: (1, .) d: (foo, .) e: (bar, .) f: (bar3, .) g: (bar3, [g-j) @4=value UPDATED) h@3: (foobar, [g-j) @4=value) i@5: (baz, [g-j) @4=value) l: (2, . UPDATED) . iter mask-filter mask-suffix=@6 first next next next next next next next ---- a: (1, .) d: (foo, .) e: (bar, .) f: (bar3, .) g: (bar3, [g-j) @4=value UPDATED) i@5: (baz, [g-j) @4=value) l: (2, . UPDATED) . # Reverse iteration test with masking. iter mask-filter mask-suffix=@6 last prev prev prev prev prev prev prev ---- l: (2, .) i@5: (baz, [g-j) @4=value UPDATED) g: (bar3, [g-j) @4=value) f: (bar3, . UPDATED) e: (bar, .) d: (foo, .) a: (1, .) . # Range del tests. reset ---- switch 1 ---- ok batch set a@3 o set b@5 foo set c@6 bar set e baz ---- flush ---- compact a-z ---- ok batch del-range b d ---- flush ---- batch set a@3 abc set b@7 notdeleted set c@9 foobar ---- flush ---- lsm ---- 0.1: 000010:[a@3#15,SET-c@9#17,SET] 0.0: 000008:[b#14,RANGEDEL-d#inf,RANGEDEL] 6: 000006:[a@3#10,SET-e#13,SET] iter first next next next next ---- a@3: (abc, .) b@7: (notdeleted, .) c@9: (foobar, .) e: (baz, .) . replicate 1 2 a z ---- replicated 1 shared SSTs switch 2 ---- ok lsm ---- 0.0: 000004:[a@3#11,SET-d#inf,RANGEDEL] 6: 000005:[a@3#10,SET-e#10,SET] iter first next next next next ---- a@3: (abc, .) b@7: (notdeleted, .) c@9: (foobar, .) e: (baz, .) . # Similar to the above test, except this time we bring the rangedel into # L5 using an ingestion. reset ---- switch 1 ---- ok batch set a@3 o set b@5 foo set c@6 bar set e baz ---- flush ---- compact a-z ---- ok build s1 del-range b d ---- ingest s1 ---- lsm ---- 5: 000007:[b#14,RANGEDEL-d#inf,RANGEDEL] 6: 000006:[a@3#10,SET-e#13,SET] batch set a@3 abc set b@7 notdeleted set c@9 foobar ---- flush ---- lsm ---- 0.0: 000009:[a@3#15,SET-c@9#17,SET] 5: 000007:[b#14,RANGEDEL-d#inf,RANGEDEL] 6: 000006:[a@3#10,SET-e#13,SET] iter first next next next next next ---- a@3: (abc, .) b@7: (notdeleted, .) c@9: (foobar, .) e: (baz, .) . . replicate 1 2 a z ---- replicated 2 shared SSTs switch 2 ---- ok lsm ---- 0.0: 000004:[a@3#12,SET-c@9#12,SET] 5: 000005:[b#11,RANGEDEL-d#inf,RANGEDEL] 6: 000006:[a@3#10,SET-e#10,SET] iter first next next next next ---- a@3: (abc, .) b@7: (notdeleted, .) c@9: (foobar, .) e: (baz, .) . # Test for cases where an excise produces a range key on one side and point keys # on the other. reset ---- switch 1 ---- ok batch range-key-set a aaa @3 foo set d foobar set e barbaz ---- flush ---- compact a-z ---- ok lsm ---- 6: 000006:[a#10,RANGEKEYSET-e#12,SET] switch 2 ---- ok batch set b bcd set c cde ---- flush ---- compact a-z ---- ok replicate 2 1 b cc ---- replicated 1 shared SSTs switch 1 ---- ok lsm ---- 6: 000009:[a#10,RANGEKEYSET-aaa#inf,RANGEKEYSET] 000008:[b#13,SET-c#13,SET] 000010:[d#11,SET-e#12,SET] iter first next next next next ---- a: (., [a-aaa) @3=foo UPDATED) b: (bcd, . UPDATED) c: (cde, .) d: (foobar, .) e: (barbaz, .) reset ---- switch 1 ---- ok batch set a@3 o set b@5 foo set c@6 bar set e baz ---- flush ---- compact a-z ---- ok build s2 del-range bb g ---- ingest s2 ---- lsm ---- 5: 000007:[bb#14,RANGEDEL-g#inf,RANGEDEL] 6: 000006:[a@3#10,SET-e#13,SET] switch 2 ---- ok batch set ff notdeleted ---- flush ---- compact a-z ---- ok lsm ---- 6: 000006:[ff#10,SET-ff#10,SET] # This replication should truncate the range deletion in pebble instance 1 # at f, leaving ff undeleted. replicate 1 2 b f ---- replicated 2 shared SSTs lsm ---- 5: 000008:[bb#12,RANGEDEL-f#inf,RANGEDEL] 6: 000009:[b@5#11,SET-e#11,SET] 000006:[ff#10,SET-ff#10,SET] iter seek-ge b next next ---- b@5: (foo, .) ff: (notdeleted, .) . # Same as above, but with a truncated range key instead of a truncated range del. reset ---- switch 1 ---- ok batch set a@3 o set b@5 foo set c@6 bar set e baz ---- flush ---- compact a-z ---- ok build s3 range-key-set bb g @8 foo ---- ingest s3 ---- lsm ---- 5: 000007:[bb#14,RANGEKEYSET-g#inf,RANGEKEYSET] 6: 000006:[a@3#10,SET-e#13,SET] switch 2 ---- ok batch set ff notcovered ---- flush ---- compact a-z ---- ok lsm ---- 6: 000006:[ff#10,SET-ff#10,SET] # This replication should truncate the range key in pebble instance 1 # at f, leaving ff uncovered. replicate 1 2 b f ---- replicated 2 shared SSTs lsm ---- 5: 000008:[bb#12,RANGEKEYSET-f#inf,RANGEKEYSET] 6: 000009:[b@5#11,SET-e#11,SET] 000006:[ff#10,SET-ff#10,SET] iter seek-ge b next next next next next ---- b@5: (foo, .) bb: (., [bb-f) @8=foo UPDATED) c@6: (bar, [bb-f) @8=foo) e: (baz, [bb-f) @8=foo) ff: (notcovered, . UPDATED) . iter mask-filter mask-suffix=@9 seek-ge b next next next next ---- b@5: (foo, .) bb: (., [bb-f) @8=foo UPDATED) e: (baz, [bb-f) @8=foo) ff: (notcovered, . UPDATED) . # Tests for Eventually file-only snapshots. reset ---- switch 1 ---- ok batch set a foo set b bar set c baz ---- flush ---- compact a-z ---- ok switch 2 ---- ok batch set b foobar ---- file-only-snapshot s1 aa bb e f ---- ok lsm ---- iter snapshot=s1 first next next ---- b: (foobar, .) . . # The below call should do a flush. wait-for-file-only-snapshot s1 ---- ok lsm ---- 0.0: 000005:[b#10,SET-b#10,SET] iter snapshot=s1 first next next ---- b: (foobar, .) . . replicate 1 2 a d ---- replicated 1 shared SSTs iter snapshot=s1 first next next ---- b: (foobar, .) . . iter first next next next ---- a: (foo, .) b: (bar, .) c: (baz, .) . switch 1 ---- ok batch del c ---- # The below excise and wait should succeed as the flush will end up transitioning # the file-only snapshot. lsm ---- 6: 000006:[a#10,SET-c#12,SET] file-only-snapshot s2 a cc ---- ok iter snapshot=s2 first next next next next ---- a: (foo, .) b: (bar, .) . . . flush ---- compact a-z ---- ok replicate 2 1 a d ---- replicated 1 shared SSTs wait-for-file-only-snapshot s2 ---- ok iter snapshot=s2 first next next next ---- a: (foo, .) b: (bar, .) . . iter snapshot=s2 first clone first next next next ---- a: (foo, .) . a: (foo, .) b: (bar, .) . . iter first next next next next ---- a: (foo, .) b: (bar, .) c: (baz, .) . . batch set d foo set e bar ---- flush ---- compact a-z ---- ok switch 2 ---- ok flush ---- batch set f foobar ---- # The below file-only snapshot is the more challenging case of a partial overlap # between an excise and a file-only snapshot. In this case the EFOS transition # blocks on the memtable but the excise proceeds through, causing the EFOS' # WaitForFileOnlySnapshot() call to error out. Opening iterators also returns # the same errors. file-only-snapshot s3 c g ---- ok iter snapshot=s3 first next next next next ---- a: (foo, .) b: (bar, .) c: (baz, .) f: (foobar, .) . iter snapshot=s3 first next clone first next next next ---- a: (foo, .) b: (bar, .) . a: (foo, .) b: (bar, .) c: (baz, .) f: (foobar, .) replicate 1 2 b e ---- replicated 2 shared SSTs wait-for-file-only-snapshot s3 ---- pebble: snapshot excised before conversion to file-only snapshot iter snapshot=s3 first next next next next ---- pebble: snapshot excised before conversion to file-only snapshot iter snapshot=s3 first next clone first next next next ---- pebble: snapshot excised before conversion to file-only snapshot iter first next next next next ---- a: (foo, .) b: (bar, .) c: (baz, .) d: (foo, .) f: (foobar, .) # The below example tests for a file-only snapshot that overlaps completely # with an excise right after it. The wait succeeds and snapshot consistency is # maintained. reset ---- switch 1 ---- ok batch set a foo set b bar set c baz ---- flush ---- compact a-z ---- ok switch 2 ---- ok batch set d foobar ---- file-only-snapshot s4 b e ---- ok iter snapshot=s4 first next next ---- d: (foobar, .) . . replicate 1 2 b e ---- replicated 1 shared SSTs wait-for-file-only-snapshot s4 ---- ok iter snapshot=s4 first next next ---- d: (foobar, .) . . compact a-z ---- ok iter snapshot=s4 first next next ---- d: (foobar, .) . . iter first next next ---- b: (bar, .) c: (baz, .) .