github.com/cockroachdb/pebble@v0.0.0-20231214172447-ab4952c5f87b/sstable/testdata/virtual_reader (about) 1 # Test 1: Start with a simple sanity checking test which uses singleLevel 2 # iterators as the backing iterator for the sstable. This will also test the 3 # compaction iterator since it's the simplest. 4 build 5 a.SET.1:a 6 b.SET.1:b 7 c.SET.1:c 8 d.SET.1:d 9 ---- 10 point: [a#1,1-d#1,1] 11 seqnums: [1-1] 12 13 # Note that the RawKeySize,RawValueSize aren't accurate here because we use 14 # Reader.EstimateDiskUsage with virtual sstables bounds to determine virtual 15 # sstable size which is then used to extrapolate virtual sstable properties, 16 # and for tiny sstables, virtual sstable sizes aren't accurate. In this 17 # testcase, the virtual sstable size is 50, whereas the backing sstable size is 18 # 850. 19 virtualize b.SET.1-c.SET.1 20 ---- 21 bounds: [b#1,1-c#1,1] 22 filenum: 000002 23 props: NumEntries: 1, RawKeySize: 3, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 24 25 citer 26 ---- 27 b#1,1:b 28 c#1,1:c 29 30 # Test 2: Similar to test 1 but force two level iterators. 31 build twoLevel 32 a.SET.1:a 33 b.SET.1:b 34 c.SET.1:c 35 d.SET.1:d 36 ---- 37 point: [a#1,1-d#1,1] 38 seqnums: [1-1] 39 40 virtualize b.SET.1-c.SET.1 41 ---- 42 bounds: [b#1,1-c#1,1] 43 filenum: 000004 44 props: NumEntries: 1, RawKeySize: 2, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 45 46 citer 47 ---- 48 b#1,1:b 49 c#1,1:c 50 51 # Test the constrain bounds function. It performs some subtle shrinking and 52 # expanding of bounds. The current virtual sstable bounds are [b,c]. 53 # 1. start key < virtual sstable start key, end key is exclusive. 54 constrain a,bb,false 55 ---- 56 b,bb,false 57 58 # 2. start key < virtual sstable start key, end key is inclusive. 59 constrain a,bb,true 60 ---- 61 b,bb,true 62 63 # 3. start key is within virtual sstable bounds, end key is at virtual sstable 64 # end bound, but is exclusive. 65 constrain bb,c,false 66 ---- 67 bb,c,false 68 69 # 3. start key is within virtual sstable bounds, end key is at virtual sstable 70 # end bound, but is inclusive. 71 constrain bb,c,true 72 ---- 73 bb,c,true 74 75 # 4. start key is within virtual sstable bounds, end key is above virtual 76 # sstable end bound and is exclusive. 77 constrain bb,e,false 78 ---- 79 bb,c,true 80 81 # 5. start key is within virtual sstable bounds, end key is above virtual 82 # sstable end bound and is inclusive. 83 constrain bb,e,true 84 ---- 85 bb,c,true 86 87 # 6. Both start, end keys fit within virtual sstable bounds. 88 constrain bb,bbb,false 89 ---- 90 bb,bbb,false 91 92 # 6. Both start, end keys are out of bounds, but overlap. 93 constrain a,d,false 94 ---- 95 b,c,true 96 97 # 7. start, end keys have no overlap with virtual sstable bounds. Note that 98 # lower becomes greater than upper here. We support this in the iterators 99 # and don't return any keys for this case. 100 constrain a,aa,false 101 ---- 102 b,aa,false 103 104 scan-range-del 105 ---- 106 107 scan-range-key 108 ---- 109 110 # Test 3: Tests raw range key/range del iterators, and makes sure that they 111 # respect virtual bounds. 112 build twoLevel 113 a.SET.1:a 114 d.SET.2:d 115 f.SET.3:f 116 d.RANGEDEL.4:e 117 rangekey: a-d:{(#11,RANGEKEYSET,@t10,foo)} 118 g.RANGEDEL.5:l 119 rangekey: y-z:{(#12,RANGEKEYSET,@t11,foo)} 120 ---- 121 point: [a#1,1-f#3,1] 122 rangedel: [d#4,15-l#72057594037927935,15] 123 rangekey: [a#11,21-z#72057594037927935,21] 124 seqnums: [1-12] 125 126 # Note that we shouldn't have range del spans which cross virtual sstable 127 # boundaries. NumRangeKeySets must be > 1. 128 virtualize a.SET.1-f.SET.1 129 ---- 130 bounds: [a#1,1-f#1,1] 131 filenum: 000006 132 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 1, ValueBlocksSize: 0 133 134 scan-range-del 135 ---- 136 d-e:{(#4,RANGEDEL)} 137 138 scan-range-key 139 ---- 140 a-d:{(#11,RANGEKEYSET,@t10,foo)} 141 142 # Test 4: Test iterators with various bounds, and various operations. This calls 143 # VirtualReader.NewIterWithBlockPropertyFilters and performs various operations 144 # on those. 145 build 146 a.SET.1:a 147 b.SET.2:b 148 c.SET.3:c 149 d.SET.4:d 150 dd.SET.5:dd 151 ddd.SET.6:ddd 152 g.SET.8:g 153 h.SET.9:h 154 ---- 155 point: [a#1,1-h#9,1] 156 seqnums: [1-9] 157 158 virtualize dd.SET.5-ddd.SET.6 159 ---- 160 bounds: [dd#5,1-ddd#6,1] 161 filenum: 000008 162 props: NumEntries: 1, RawKeySize: 10, RawValueSize: 2, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 163 164 # Check lower bound enforcement during SeekPrefixGE. 165 iter 166 seek-prefix-ge d 167 next 168 next 169 ---- 170 <dd:5>:dd 171 <ddd:6>:ddd 172 . 173 174 # Build a simpler sstable for the rest of the tests. 175 build 176 a.SET.1:a 177 b.SET.2:b 178 c.SET.3:c 179 d.SET.4:d 180 e.SET.5:e 181 f.SET.6:f 182 g.SET.8:g 183 h.SET.9:h 184 ---- 185 point: [a#1,1-h#9,1] 186 seqnums: [1-9] 187 188 # Set bounds c-f for the virtual sstable. 189 virtualize c.SET.3-f.SET.6 190 ---- 191 bounds: [c#3,1-f#6,1] 192 filenum: 000010 193 props: NumEntries: 1, RawKeySize: 9, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 194 195 # Just test a basic iterator once virtual sstable bounds have been set. 196 iter 197 first 198 next 199 next 200 next 201 next 202 ---- 203 <c:3>:c 204 <d:4>:d 205 <e:5>:e 206 <f:6>:f 207 . 208 209 # Create an iterator with bounds. External bounds should still be restricted 210 # along with virtual sstable bounds. 211 iter a-d 212 first 213 next 214 ---- 215 <c:3>:c 216 . 217 218 iter d-g 219 first 220 next 221 next 222 next 223 ---- 224 <d:4>:d 225 <e:5>:e 226 <f:6>:f 227 . 228 229 # e is turned into an exclusive bounds, and thus it is hidden. 230 iter 231 set-bounds lower=d upper=e 232 first 233 next 234 ---- 235 . 236 <d:4>:d 237 . 238 239 # Virtual sstable lower bound must be enforced internally from within the 240 # iterator. 241 iter 242 seek-ge b 243 next 244 next 245 next 246 next 247 ---- 248 <c:3>:c 249 <d:4>:d 250 <e:5>:e 251 <f:6>:f 252 . 253 254 # Upper bound enforcement by SeekGE. 255 iter 256 seek-ge g 257 ---- 258 . 259 260 # Test prev. 261 iter 262 seek-ge d 263 prev 264 next 265 prev 266 prev 267 ---- 268 <d:4>:d 269 <c:3>:c 270 <d:4>:d 271 <c:3>:c 272 . 273 274 # Test SeekLT 275 build 276 a.SET.1:a 277 b.SET.2:b 278 c.SET.3:c 279 d.SET.4:d 280 e.SET.5:e 281 f.SET.6:f 282 f.SET.1:ff 283 g.SET.8:g 284 h.SET.9:h 285 ---- 286 point: [a#1,1-h#9,1] 287 seqnums: [1-9] 288 289 virtualize c.SET.3-f.SET.1:ff 290 ---- 291 bounds: [c#3,1-f#0,1] 292 filenum: 000012 293 props: NumEntries: 2, RawKeySize: 11, RawValueSize: 2, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 3 294 295 iter 296 set-bounds lower=d upper=e 297 seek-lt e 298 ---- 299 . 300 <d:4>:d 301 302 iter 303 seek-ge f 304 next 305 next 306 ---- 307 <f:6>:f 308 <f:1>:ff 309 . 310 311 iter 312 seek-lt f 313 next 314 next 315 prev 316 prev 317 prev 318 prev 319 prev 320 ---- 321 <e:5>:e 322 <f:6>:f 323 <f:1>:ff 324 <f:6>:f 325 <e:5>:e 326 <d:4>:d 327 <c:3>:c 328 . 329 330 # We should get f here, not g as SeekLT will apply the virtual sstable end 331 # bound. 332 iter 333 seek-lt h 334 ---- 335 <f:1>:ff 336 337 iter 338 last 339 ---- 340 <f:1>:ff 341 342 virtualize f.SET.6-h.SET.9 343 ---- 344 bounds: [f#6,1-h#9,1] 345 filenum: 000013 346 props: NumEntries: 2, RawKeySize: 11, RawValueSize: 2, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 3 347 348 iter 349 seek-lt z 350 ---- 351 <h:9>:h 352 353 iter 354 last 355 ---- 356 <h:9>:h 357 358 iter 359 set-bounds lower=c upper=g 360 first 361 last 362 ---- 363 . 364 <f:6>:f 365 <f:1>:ff 366 367 # Test 5: Same as test 4, but force two level iterators. 368 build twoLevel 369 a.SET.1:a 370 b.SET.2:b 371 c.SET.3:c 372 d.SET.4:d 373 dd.SET.5:dd 374 ddd.SET.6:ddd 375 g.SET.8:g 376 h.SET.9:h 377 ---- 378 point: [a#1,1-h#9,1] 379 seqnums: [1-9] 380 381 virtualize dd.SET.5-ddd.SET.6 382 ---- 383 bounds: [dd#5,1-ddd#6,1] 384 filenum: 000015 385 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 386 387 # Check lower bound enforcement during SeekPrefixGE. 388 iter 389 seek-prefix-ge d 390 next 391 next 392 ---- 393 <dd:5>:dd 394 <ddd:6>:ddd 395 . 396 397 # Build a simpler sstable for the rest of the tests. 398 build twoLevel 399 a.SET.1:a 400 b.SET.2:b 401 c.SET.3:c 402 d.SET.4:d 403 e.SET.5:e 404 f.SET.6:f 405 g.SET.8:g 406 h.SET.9:h 407 ---- 408 point: [a#1,1-h#9,1] 409 seqnums: [1-9] 410 411 # Set bounds c-f for the virtual sstable. 412 virtualize c.SET.3-f.SET.6 413 ---- 414 bounds: [c#3,1-f#6,1] 415 filenum: 000017 416 props: NumEntries: 1, RawKeySize: 7, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 417 418 # Just test a basic iterator once virtual sstable bounds have been set. 419 iter 420 first 421 next 422 next 423 next 424 next 425 ---- 426 <c:3>:c 427 <d:4>:d 428 <e:5>:e 429 <f:6>:f 430 . 431 432 # Create an iterator with bounds. External bounds should still be restricted 433 # along with virtual sstable bounds. 434 iter a-d 435 first 436 next 437 ---- 438 <c:3>:c 439 . 440 441 iter d-g 442 first 443 next 444 next 445 next 446 ---- 447 <d:4>:d 448 <e:5>:e 449 <f:6>:f 450 . 451 452 # e is turned into an exclusive bounds, and thus it is hidden. 453 iter 454 set-bounds lower=d upper=e 455 first 456 next 457 ---- 458 . 459 <d:4>:d 460 . 461 462 # Virtual sstable lower bound must be enforced internally from within the 463 # iterator. 464 iter 465 seek-ge b 466 next 467 next 468 next 469 next 470 ---- 471 <c:3>:c 472 <d:4>:d 473 <e:5>:e 474 <f:6>:f 475 . 476 477 # Upper bound enforcement by SeekGE. 478 iter 479 seek-ge g 480 ---- 481 . 482 483 # Test prev. 484 iter 485 seek-ge d 486 prev 487 next 488 prev 489 prev 490 ---- 491 <d:4>:d 492 <c:3>:c 493 <d:4>:d 494 <c:3>:c 495 . 496 497 # Test SeekLT 498 build twoLevel 499 a.SET.1:a 500 b.SET.2:b 501 c.SET.3:c 502 d.SET.4:d 503 e.SET.5:e 504 f.SET.6:f 505 f.SET.1:ff 506 g.SET.8:g 507 h.SET.9:h 508 ---- 509 point: [a#1,1-h#9,1] 510 seqnums: [1-9] 511 512 virtualize c.SET.3-f.SET.1:ff 513 ---- 514 bounds: [c#3,1-f#0,1] 515 filenum: 000019 516 props: NumEntries: 1, RawKeySize: 7, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 2 517 518 iter 519 set-bounds lower=d upper=e 520 seek-lt e 521 ---- 522 . 523 <d:4>:d 524 525 iter 526 seek-ge f 527 next 528 next 529 ---- 530 <f:6>:f 531 <f:1>:ff 532 . 533 534 iter 535 seek-lt f 536 next 537 next 538 prev 539 prev 540 prev 541 prev 542 prev 543 ---- 544 <e:5>:e 545 <f:6>:f 546 <f:1>:ff 547 <f:6>:f 548 <e:5>:e 549 <d:4>:d 550 <c:3>:c 551 . 552 553 # We should get f here, not g as SeekLT will apply the virtual sstable end 554 # bound. 555 iter 556 seek-lt h 557 ---- 558 <f:1>:ff 559 560 iter 561 last 562 ---- 563 <f:1>:ff 564 565 virtualize f.SET.6-h.SET.9 566 ---- 567 bounds: [f#6,1-h#9,1] 568 filenum: 000020 569 props: NumEntries: 1, RawKeySize: 7, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 2 570 571 iter 572 seek-lt z 573 ---- 574 <h:9>:h 575 576 iter 577 last 578 ---- 579 <h:9>:h 580 581 iter 582 set-bounds lower=c upper=g 583 first 584 last 585 ---- 586 . 587 <f:6>:f 588 <f:1>:ff 589 590 # Test 6: Exclusive sentinel handling. Note that this test only ensures that 591 # exclusive sentinel handling is correct for some code path, but not all of 592 # them, in the iterators. Consider a randomized test. 593 build 594 a.SET.1:a 595 d.SET.2:d 596 e.SET.3:e 597 d.RANGEDEL.4:e 598 f.SET.5:f 599 ---- 600 point: [a#1,1-f#5,1] 601 rangedel: [d#4,15-e#72057594037927935,15] 602 seqnums: [1-5] 603 604 virtualize a.SET.1-e.RANGEDEL.72057594037927935 605 ---- 606 bounds: [a#1,1-e#72057594037927935,15] 607 filenum: 000022 608 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 609 610 iter 611 first 612 next 613 next 614 seek-lt f 615 ---- 616 <a:1>:a 617 <d:2>:d 618 . 619 <d:2>:d 620 621 # Don't expose e from the compaction iter. 622 citer 623 ---- 624 a#1,1:a 625 d#2,1:d 626 627 scan-range-del 628 ---- 629 d-e:{(#4,RANGEDEL)} 630 631 632 build twoLevel 633 a.SET.1:a 634 d.SET.2:d 635 e.SET.3:e 636 d.RANGEDEL.4:e 637 f.SET.5:f 638 ---- 639 point: [a#1,1-f#5,1] 640 rangedel: [d#4,15-e#72057594037927935,15] 641 seqnums: [1-5] 642 643 virtualize a.SET.1-e.RANGEDEL.72057594037927935 644 ---- 645 bounds: [a#1,1-e#72057594037927935,15] 646 filenum: 000024 647 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 648 649 iter 650 first 651 next 652 next 653 seek-lt f 654 ---- 655 <a:1>:a 656 <d:2>:d 657 . 658 <d:2>:d 659 660 # Don't expose e from the compaction iter. 661 citer 662 ---- 663 a#1,1:a 664 d#2,1:d 665 666 scan-range-del 667 ---- 668 d-e:{(#4,RANGEDEL)} 669 670 # Test NumRangeKeySets. 671 build twoLevel 672 a.SET.1:a 673 b.SET.5:b 674 d.SET.2:d 675 f.SET.3:f 676 d.RANGEDEL.4:e 677 rangekey: a-d:{(#11,RANGEKEYSET,@t10,foo)} 678 g.RANGEDEL.5:l 679 rangekey: y-z:{(#12,RANGEKEYSET,@t11,foo)} 680 ---- 681 point: [a#1,1-f#3,1] 682 rangedel: [d#4,15-l#72057594037927935,15] 683 rangekey: [a#11,21-z#72057594037927935,21] 684 seqnums: [1-12] 685 686 # Virtual sstable doesn't contain range key set, but NumRangeKeySets in the 687 # properties must be > 0. 688 virtualize a.SET.1-b.SET.5 689 ---- 690 bounds: [a#1,1-b#5,1] 691 filenum: 000026 692 props: NumEntries: 1, RawKeySize: 3, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 1, ValueBlocksSize: 0