# 1 memtable. define mem a.SET.10:b a.SET.12:c a.SET.14:d b.MERGE.10:b b.MERGE.12:c b.MERGE.14:d b.RANGEDEL.15:c b.MERGE.16:e c.SET.10:b c.SET.12:c c.SET.14:d ---- mem: 1 get seq=11 a b c ---- a:b b:b c:b get seq=13 a b c ---- a:c b:bc c:c get seq=15 a b c ---- a:d b:bcd c:d get seq=16 a b c ---- a:d b: pebble: not found c:d get seq=17 a b c ---- a:d b:e c:d get seq=15 a b c ---- a:d b:bcd c:d iter seq=15 first next next next seek-ge a seek-ge b seek-ge c seek-ge d last prev prev prev seek-lt a seek-lt b seek-lt c seek-lt d ---- a: (d, .) b: (bcd, .) c: (d, .) . a: (d, .) b: (bcd, .) c: (d, .) . c: (d, .) b: (bcd, .) a: (d, .) . . a: (d, .) b: (bcd, .) c: (d, .) iter seq=16 first next next seek-ge a seek-ge b seek-ge c seek-ge d last prev prev seek-lt a seek-lt b seek-lt c seek-lt d ---- a: (d, .) c: (d, .) . a: (d, .) c: (d, .) c: (d, .) . c: (d, .) a: (d, .) . . a: (d, .) a: (d, .) c: (d, .) # Multiple memtables. define mem a.SET.10:b b.MERGE.10:b c.SET.10:b mem a.SET.12:c b.MERGE.12:c c.SET.12:c mem a.SET.14:d b.MERGE.14:d c.SET.14:d mem b.RANGEDEL.15:c mem b.MERGE.16:e ---- mem: 5 get seq=11 a b c ---- a:b b:b c:b get seq=13 a b c ---- a:c b:bc c:c get seq=15 a b c ---- a:d b:bcd c:d get seq=16 a b c ---- a:d b: pebble: not found c:d get seq=17 a b c ---- a:d b:e c:d get seq=15 a b c ---- a:d b:bcd c:d iter seq=15 first next next next seek-ge a seek-ge b seek-ge c seek-ge d last prev prev prev seek-lt a seek-lt b seek-lt c seek-lt d ---- a: (d, .) b: (bcd, .) c: (d, .) . a: (d, .) b: (bcd, .) c: (d, .) . c: (d, .) b: (bcd, .) a: (d, .) . . a: (d, .) b: (bcd, .) c: (d, .) iter seq=16 first next next seek-ge a seek-ge b seek-ge c seek-ge d last prev prev seek-lt a seek-lt b seek-lt c seek-lt d ---- a: (d, .) c: (d, .) . a: (d, .) c: (d, .) c: (d, .) . c: (d, .) a: (d, .) . . a: (d, .) a: (d, .) c: (d, .) # Overlapping range deletions in the same memtable. define mem a.SET.10:1 a.SET.12:2 a.SET.14:3 a.SET.16:4 b.SET.10:1 b.SET.12:2 b.SET.14:3 b.SET.16:4 c.SET.10:1 c.SET.12:2 c.SET.14:3 c.SET.16:4 d.SET.10:1 d.SET.12:2 d.SET.14:3 d.SET.16:4 a.RANGEDEL.11:b b.RANGEDEL.13:c b.RANGEDEL.11:c c.RANGEDEL.15:d c.RANGEDEL.13:d c.RANGEDEL.11:d ---- mem: 1 get seq=11 a b c d ---- a:1 b:1 c:1 d:1 get seq=12 a b c d ---- a: pebble: not found b: pebble: not found c: pebble: not found d:1 get seq=14 a b c d ---- a:2 b: pebble: not found c: pebble: not found d:2 get seq=16 a b c d ---- a:3 b:3 c: pebble: not found d:3 get seq=18 a b c d ---- a:4 b:4 c:4 d:4 iter seq=11 first next next next next last prev prev prev prev ---- a: (1, .) b: (1, .) c: (1, .) d: (1, .) . d: (1, .) c: (1, .) b: (1, .) a: (1, .) . iter seq=12 first next last prev ---- d: (1, .) . d: (1, .) . iter seq=14 first next next last prev prev ---- a: (2, .) d: (2, .) . d: (2, .) a: (2, .) . iter seq=16 first next next next last prev prev prev ---- a: (3, .) b: (3, .) d: (3, .) . d: (3, .) b: (3, .) a: (3, .) . iter seq=18 first next next next next last prev prev prev prev ---- a: (4, .) b: (4, .) c: (4, .) d: (4, .) . d: (4, .) c: (4, .) b: (4, .) a: (4, .) . # Overlapping range deletions in different memtables. Note that the # range tombstones are not fragmented in this case. define mem a.SET.10:1 b.SET.10:1 c.SET.10:1 d.SET.10:1 mem a.SET.12:2 b.SET.12:2 c.SET.12:2 d.SET.12:2 a.RANGEDEL.11:d mem a.SET.14:3 b.SET.14:3 c.SET.14:3 d.SET.14:3 b.RANGEDEL.13:d mem a.SET.16:4 b.SET.16:4 c.SET.16:4 d.SET.16:4 c.RANGEDEL.13:d ---- mem: 4 get seq=11 a b c d ---- a:1 b:1 c:1 d:1 get seq=12 a b c d ---- a: pebble: not found b: pebble: not found c: pebble: not found d:1 get seq=14 a b c d ---- a:2 b: pebble: not found c: pebble: not found d:2 get seq=16 a b c d ---- a:3 b:3 c: pebble: not found d:3 get seq=18 a b c d ---- a:4 b:4 c:4 d:4 iter seq=11 first next next next next last prev prev prev prev ---- a: (1, .) b: (1, .) c: (1, .) d: (1, .) . d: (1, .) c: (1, .) b: (1, .) a: (1, .) . iter seq=12 first next last prev ---- d: (1, .) . d: (1, .) . iter seq=14 first next next last prev prev ---- a: (2, .) d: (2, .) . d: (2, .) a: (2, .) . iter seq=16 first next next next last prev prev prev ---- a: (3, .) b: (3, .) d: (3, .) . d: (3, .) b: (3, .) a: (3, .) . iter seq=18 first next next next next last prev prev prev prev ---- a: (4, .) b: (4, .) c: (4, .) d: (4, .) . d: (4, .) c: (4, .) b: (4, .) a: (4, .) . # User-key that spans tables in a level. define L1 a.SET.12:3 L1 a.SET.11:2 L1 a.SET.10:1 ---- mem: 1 1: 000004:[a#12,SET-a#12,SET] 000005:[a#11,SET-a#11,SET] 000006:[a#10,SET-a#10,SET] get seq=10 a ---- a: pebble: not found get seq=11 a ---- a:1 get seq=12 a ---- a:2 get seq=13 a ---- a:3 iter seq=11 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (1, .) a: (1, .) . a: (1, .) . a: (1, .) iter seq=12 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (2, .) a: (2, .) . a: (2, .) . a: (2, .) iter seq=13 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (3, .) a: (3, .) . a: (3, .) . a: (3, .) define L1 a.MERGE.12:3 L1 a.MERGE.11:2 L1 a.MERGE.10:1 ---- mem: 1 1: 000004:[a#12,MERGE-a#12,MERGE] 000005:[a#11,MERGE-a#11,MERGE] 000006:[a#10,MERGE-a#10,MERGE] get seq=10 a ---- a: pebble: not found get seq=11 a ---- a:1 get seq=12 a ---- a:12 get seq=13 a ---- a:123 iter seq=11 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (1, .) a: (1, .) . a: (1, .) . a: (1, .) iter seq=12 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (12, .) a: (12, .) . a: (12, .) . a: (12, .) iter seq=13 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (123, .) a: (123, .) . a: (123, .) . a: (123, .) # User-key spread across multiple levels. define mem a.MERGE.13:4 L1 a.MERGE.12:3 L2 a.MERGE.11:2 L3 a.MERGE.10:1 ---- mem: 1 1: 000004:[a#12,MERGE-a#12,MERGE] 2: 000005:[a#11,MERGE-a#11,MERGE] 3: 000006:[a#10,MERGE-a#10,MERGE] get seq=10 a ---- a: pebble: not found get seq=11 a ---- a:1 get seq=12 a ---- a:12 get seq=13 a ---- a:123 get seq=14 a ---- a:1234 iter seq=11 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (1, .) a: (1, .) . a: (1, .) . a: (1, .) iter seq=12 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (12, .) a: (12, .) . a: (12, .) . a: (12, .) iter seq=13 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (123, .) a: (123, .) . a: (123, .) . a: (123, .) iter seq=14 first seek-ge a seek-ge b last seek-lt a seek-lt b ---- a: (1234, .) a: (1234, .) . a: (1234, .) . a: (1234, .) # Range deletions on multiple levels. define L0 a.SET.13:4 b.SET.13:4 d.SET.13:4 c.RANGEDEL.13:d L1 a.SET.12:3 d.SET.12:3 b.RANGEDEL.12:d L2 d.SET.11:2 a.RANGEDEL.11:d L3 a.SET.10:1 b.SET.10:1 c.SET.10:1 d.SET.10:1 ---- mem: 1 0.0: 000004:[a#13,SET-d#13,SET] 1: 000005:[a#12,SET-d#12,SET] 2: 000006:[a#11,RANGEDEL-d#11,SET] 3: 000007:[a#10,SET-d#10,SET] get seq=11 a b c d ---- a:1 b:1 c:1 d:1 get seq=12 a b c d ---- a: pebble: not found b: pebble: not found c: pebble: not found d:2 get seq=13 a b c d ---- a:3 b: pebble: not found c: pebble: not found d:3 get seq=14 a b c d ---- a:4 b:4 c: pebble: not found d:4 iter seq=11 first next next next last prev prev prev ---- a: (1, .) b: (1, .) c: (1, .) d: (1, .) d: (1, .) c: (1, .) b: (1, .) a: (1, .) iter seq=12 first last ---- d: (2, .) d: (2, .) iter seq=13 first next last prev ---- a: (3, .) d: (3, .) d: (3, .) a: (3, .) iter seq=14 first next next last prev prev ---- a: (4, .) b: (4, .) d: (4, .) d: (4, .) b: (4, .) a: (4, .) # Range deletions spanning tables within a level. define mem a.SET.12:3 b.SET.12:3 c.SET.12:3 d.SET.12:3 L1 a.RANGEDEL.11:b L1 b.RANGEDEL.11:c L1 c.RANGEDEL.11:d L2 a.SET.10:1 b.SET.10:1 c.SET.10:1 d.SET.10:1 ---- mem: 1 1: 000004:[a#11,RANGEDEL-b#inf,RANGEDEL] 000005:[b#11,RANGEDEL-c#inf,RANGEDEL] 000006:[c#11,RANGEDEL-d#inf,RANGEDEL] 2: 000007:[a#10,SET-d#10,SET] get seq=11 a b c d ---- a:1 b:1 c:1 d:1 get seq=12 a b c d ---- a: pebble: not found b: pebble: not found c: pebble: not found d:1 get seq=13 a b c d ---- a:3 b:3 c:3 d:3 iter seq=11 first next next next last prev prev prev ---- a: (1, .) b: (1, .) c: (1, .) d: (1, .) d: (1, .) c: (1, .) b: (1, .) a: (1, .) iter seq=12 first last ---- d: (1, .) d: (1, .) iter seq=13 first next next next last prev prev prev ---- a: (3, .) b: (3, .) c: (3, .) d: (3, .) d: (3, .) c: (3, .) b: (3, .) a: (3, .) # Invalid LSM structure (range deletion at newer level covers newer # write at an older level). This LSM structure is not generated # naturally, but tested here to show the level-by-level nature of Get. define L1 a.RANGEDEL.10:b L2 a.SET.11:2 ---- mem: 1 1: 000004:[a#10,RANGEDEL-b#inf,RANGEDEL] 2: 000005:[a#11,SET-a#11,SET] get seq=12 a ---- a: pebble: not found # A range tombstone straddles two SSTs. One is compacted to a lower level. Its # keys that are newer than the range tombstone should not disappear. # # Uses a snapshot to prevent range tombstone from being elided when it gets # compacted to the bottommost level. define target-file-sizes=(100, 1) snapshots=(1) L0 a.RANGEDEL.10:e L0 a.SET.11:v L0 c.SET.12:v ---- mem: 1 0.1: 000005:[a#11,SET-a#11,SET] 000006:[c#12,SET-c#12,SET] 0.0: 000004:[a#10,RANGEDEL-e#inf,RANGEDEL] compact a-e ---- 1: 000007:[a#11,SET-c#inf,RANGEDEL] 000008:[c#12,SET-e#inf,RANGEDEL] compact d-e ---- 1: 000007:[a#11,SET-c#inf,RANGEDEL] 2: 000008:[c#12,SET-e#inf,RANGEDEL] iter seq=13 seek-ge b next ---- c: (v, .) . # Reverse the above test: compact the left file containing the split range # tombstone downwards, and iterate from right to left. define target-file-sizes=(100, 1) snapshots=(1) L0 a.RANGEDEL.10:e L0 a.SET.11:v L0 c.SET.12:v ---- mem: 1 0.1: 000005:[a#11,SET-a#11,SET] 000006:[c#12,SET-c#12,SET] 0.0: 000004:[a#10,RANGEDEL-e#inf,RANGEDEL] compact a-e ---- 1: 000007:[a#11,SET-c#inf,RANGEDEL] 000008:[c#12,SET-e#inf,RANGEDEL] compact a-b ---- 1: 000008:[c#12,SET-e#inf,RANGEDEL] 2: 000007:[a#11,SET-c#inf,RANGEDEL] iter seq=13 seek-lt d prev prev ---- c: (v, .) a: (v, .) . # A range tombstone straddles two sstables. One is compacted two # levels lower. The other is compacted one level lower. The one that # is compacted one level lower should not see its boundaries expand # causing it to delete more keys. A snapshot is used to prevent range # tombstone from being elided when it gets compacted to the bottommost # level. define target-file-sizes=(100, 1) snapshots=(1) L0 a.RANGEDEL.10:e L0 a.SET.11:v L0 c.SET.12:v L2 d.SET.0:v ---- mem: 1 0.1: 000005:[a#11,SET-a#11,SET] 000006:[c#12,SET-c#12,SET] 0.0: 000004:[a#10,RANGEDEL-e#inf,RANGEDEL] 2: 000007:[d#0,SET-d#0,SET] compact a-b ---- 1: 000008:[a#11,SET-c#inf,RANGEDEL] 000009:[c#12,SET-d#inf,RANGEDEL] 000010:[d#10,RANGEDEL-e#inf,RANGEDEL] 2: 000007:[d#0,SET-d#0,SET] compact d-e ---- 1: 000008:[a#11,SET-c#inf,RANGEDEL] 000009:[c#12,SET-d#inf,RANGEDEL] 3: 000011:[d#10,RANGEDEL-e#inf,RANGEDEL] get seq=13 c ---- c:v compact a-b L1 ---- 1: 000009:[c#12,SET-d#inf,RANGEDEL] 2: 000008:[a#11,SET-c#inf,RANGEDEL] 3: 000011:[d#10,RANGEDEL-e#inf,RANGEDEL] get seq=13 c ---- c:v # A slight variation on the scenario above where a range tombstone is # expanded past the boundaries of its "atomic compaction unit". define target-file-sizes=(100, 1) snapshots=(1) L0 a.RANGEDEL.10:e L0 a.SET.11:v L0 c.SET.12:v L0 f.SET.13:v L2 d.SET.0:v ---- mem: 1 0.1: 000005:[a#11,SET-a#11,SET] 000006:[c#12,SET-c#12,SET] 0.0: 000004:[a#10,RANGEDEL-e#inf,RANGEDEL] 000007:[f#13,SET-f#13,SET] 2: 000008:[d#0,SET-d#0,SET] compact a-b ---- 0.0: 000007:[f#13,SET-f#13,SET] 1: 000009:[a#11,SET-c#inf,RANGEDEL] 000010:[c#12,SET-d#inf,RANGEDEL] 000011:[d#10,RANGEDEL-e#inf,RANGEDEL] 2: 000008:[d#0,SET-d#0,SET] compact d-e ---- 0.0: 000007:[f#13,SET-f#13,SET] 1: 000009:[a#11,SET-c#inf,RANGEDEL] 000010:[c#12,SET-d#inf,RANGEDEL] 3: 000012:[d#10,RANGEDEL-e#inf,RANGEDEL] get seq=13 c ---- c:v compact f-f L0 ---- 1: 000009:[a#11,SET-c#inf,RANGEDEL] 000010:[c#12,SET-d#inf,RANGEDEL] 000007:[f#13,SET-f#13,SET] 3: 000012:[d#10,RANGEDEL-e#inf,RANGEDEL] compact a-f L1 ---- 2: 000013:[a#11,SET-c#inf,RANGEDEL] 000014:[c#12,SET-d#inf,RANGEDEL] 000015:[f#13,SET-f#13,SET] 3: 000012:[d#10,RANGEDEL-e#inf,RANGEDEL] get seq=13 c ---- c:v define L0 a.RANGEDEL.12:f L0 a.RANGEDEL.13:c c.RANGEDEL.13:f L1 b.RANGEDEL.11:e L2 c.RANGEDEL.10:d ---- mem: 1 0.1: 000005:[a#13,RANGEDEL-f#inf,RANGEDEL] 0.0: 000004:[a#12,RANGEDEL-f#inf,RANGEDEL] 1: 000006:[b#11,RANGEDEL-e#inf,RANGEDEL] 2: 000007:[c#10,RANGEDEL-d#inf,RANGEDEL] wait-pending-table-stats 000007 ---- num-entries: 1 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 0 wait-pending-table-stats 000006 ---- num-entries: 1 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 836 wait-pending-table-stats 000004 ---- num-entries: 1 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 1672 wait-pending-table-stats 000005 ---- num-entries: 2 num-deletions: 2 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 1672 # Range deletions with varying overlap. define L0 a.SET.13:4 b.SET.13:4 d.SET.13:4 c.RANGEDEL.13:d L1 a.SET.12:3 d.SET.12:3 b.RANGEDEL.12:d L2 d.SET.11:2 a.RANGEDEL.11:d L3 a.SET.10:1 b.SET.10:1 c.SET.10:1 d.SET.10:1 ---- mem: 1 0.0: 000004:[a#13,SET-d#13,SET] 1: 000005:[a#12,SET-d#12,SET] 2: 000006:[a#11,RANGEDEL-d#11,SET] 3: 000007:[a#10,SET-d#10,SET] wait-pending-table-stats 000007 ---- num-entries: 4 num-deletions: 0 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 0 wait-pending-table-stats 000006 ---- num-entries: 2 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 42 wait-pending-table-stats 000005 ---- num-entries: 3 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 68 wait-pending-table-stats 000004 ---- num-entries: 4 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 100 # Multiple Range deletions in a table. define L0 a.RANGEDEL.15:d e.RANGEDEL.15:z L0 a.RANGEDEL.14:d L0 e.RANGEDEL.13:z L1 a.SET.11:1 b.SET.11:1 c.SET.11:1 L2 x.SET.10:2 ---- mem: 1 0.1: 000004:[a#15,RANGEDEL-z#inf,RANGEDEL] 0.0: 000005:[a#14,RANGEDEL-d#inf,RANGEDEL] 000006:[e#13,RANGEDEL-z#inf,RANGEDEL] 1: 000007:[a#11,SET-c#11,SET] 2: 000008:[x#10,SET-x#10,SET] wait-pending-table-stats 000005 ---- num-entries: 1 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 782 wait-pending-table-stats 000006 ---- num-entries: 1 num-deletions: 1 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 771 wait-pending-table-stats 000004 ---- num-entries: 2 num-deletions: 2 num-range-key-sets: 0 point-deletions-bytes-estimate: 0 range-deletions-bytes-estimate: 1553