Commit ec03187
authored
perf: seek past the internal-key region instead of stepping through it (#1243)
### Motivation
Item 2.2 from the performance review. Floor/ceiling gets and unbounded
scans that exclude internal keys used pebble's `SkipPoint`. `SkipPoint`
is a **filter, not a seek**: the iterator still steps through — and
loads the blocks of — every internal key it passes. A `CEILING`/`HIGHER`
get past the last user key, or a scan with no upper bound, therefore
walks the **entire live notification backlog** before returning. With
100k notifications retained a single client `Get` took **3 ms**, and the
cost grows without bound with the retention window.
### The subtlety (why the obvious fix is wrong)
The internal keys are contiguous, so the tempting fix is to clamp the
iterator's `UpperBound` to the start of the internal region. That is
**unsafe for natural sorting**: a regular key is stored raw, so one
whose bytes sort after the encoded internal prefix `"\xff\xffoxia/"` —
e.g. `"\xff\xffz"` — lives *after* the internal keys. Bounding the
region away would silently hide those keys. Hierarchical sorting is
different: the marker bit puts internal keys strictly last, so a bound
*is* safe there.
### Changes
`Encoder` gains `InternalKeyRange() (start, end []byte)`, returning the
contiguous internal-key region as a half-open range:
- **hierarchical** → `end == nil` (region runs to the end of the
keyspace): pruned outright with an `UpperBound`, so pebble never visits
it.
- **natural** → real `end`: the region is **seeked over** in a single
jump (it is contiguous, so nothing at/after `end` is internal), in
**both directions** — the reverse paths had the same walk, a floor probe
above the region stepped *backwards* through the whole backlog.
`SkipPoint` is removed on these paths. Besides causing the walk, it
hides the internal keys from the wrapper, so we could not detect the
region in order to seek past it — the two approaches are mutually
exclusive. The skipper is applied at every positioning op (the four
point lookups plus `Next`/`Prev`/`SeekGE`/`SeekLT` in both iterator
wrappers) so no internal key can leak. `InternalKeyRange` is
allocation-free for both encoders (constant, read-only bounds shared as
package vars).
### Benchmark
`BenchmarkPebbleGetCeilingPastUserKeys` — ceiling lookup past the last
user key, N internal keys retained:
| backlog | before (SkipPoint) | after (seek) |
|---|---|---|
| 100 | 4.1 µs | 1.23 µs |
| 10,000 | 295 µs | 1.26 µs |
| 100,000 | **3.05 ms** | **1.27 µs** |
O(N) → O(1).
### Verification
- `TestPebbleScanSkipsInternalRegionButKeepsKeysAfterIt` and
`TestPebbleGetAcrossInternalRegionNatural` plant a regular key **after**
the internal region under natural sorting and assert scans/gets in both
directions still return it. Verified to discriminate: they fail against
an upper-bound prune (`end == nil` for natural) — exactly the mistake
the naive fix would make.
- `TestPebbleGetPastInternalRegionHierarchical` pins that hierarchical
ceilings past the user keys are genuinely `NOT_FOUND` without walking
the region.
- `go test -race` green on `oxiad/dataserver/...` and `common/compare`;
`golangci-lint` clean across all go.work modules on the CI-pinned v2.6.2
(the change spans `common/` and `oxiad/`).
---
Stacked on #1242 (drops a redundant seek in `getHigher`, which this PR
also rewrites); please merge that first. Until it does, its one commit
shows in this PR's diff.
---------
Signed-off-by: Matteo Merli <mmerli@apache.org>1 parent d27c02a commit ec03187
3 files changed
Lines changed: 362 additions & 58 deletions
File tree
- common/compare
- oxiad/dataserver/database/kvstore
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
33 | 57 | | |
34 | 58 | | |
35 | 59 | | |
36 | 60 | | |
37 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
38 | 66 | | |
39 | 67 | | |
40 | 68 | | |
| |||
105 | 133 | | |
106 | 134 | | |
107 | 135 | | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
108 | 149 | | |
109 | 150 | | |
110 | 151 | | |
| |||
163 | 204 | | |
164 | 205 | | |
165 | 206 | | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
166 | 217 | | |
167 | 218 | | |
168 | 219 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
430 | 430 | | |
431 | 431 | | |
432 | 432 | | |
433 | | - | |
434 | | - | |
435 | | - | |
| 433 | + | |
436 | 434 | | |
437 | 435 | | |
438 | 436 | | |
| 437 | + | |
439 | 438 | | |
440 | | - | |
| 439 | + | |
441 | 440 | | |
442 | 441 | | |
443 | 442 | | |
| |||
447 | 446 | | |
448 | 447 | | |
449 | 448 | | |
450 | | - | |
451 | | - | |
452 | | - | |
| 449 | + | |
453 | 450 | | |
454 | 451 | | |
455 | 452 | | |
| 453 | + | |
456 | 454 | | |
457 | | - | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
458 | 458 | | |
459 | 459 | | |
460 | 460 | | |
| |||
464 | 464 | | |
465 | 465 | | |
466 | 466 | | |
467 | | - | |
468 | | - | |
469 | | - | |
| 467 | + | |
470 | 468 | | |
471 | 469 | | |
472 | 470 | | |
| 471 | + | |
473 | 472 | | |
474 | | - | |
| 473 | + | |
475 | 474 | | |
476 | 475 | | |
477 | 476 | | |
478 | 477 | | |
479 | 478 | | |
480 | 479 | | |
481 | | - | |
| 480 | + | |
482 | 481 | | |
483 | 482 | | |
484 | 483 | | |
| |||
521 | 520 | | |
522 | 521 | | |
523 | 522 | | |
524 | | - | |
525 | | - | |
526 | | - | |
527 | | - | |
528 | | - | |
529 | | - | |
530 | | - | |
| 523 | + | |
531 | 524 | | |
532 | 525 | | |
533 | 526 | | |
534 | 527 | | |
535 | | - | |
| 528 | + | |
536 | 529 | | |
537 | 530 | | |
538 | 531 | | |
539 | | - | |
540 | | - | |
541 | | - | |
542 | | - | |
543 | | - | |
544 | | - | |
| 532 | + | |
545 | 533 | | |
546 | | - | |
| 534 | + | |
547 | 535 | | |
548 | 536 | | |
549 | | - | |
| 537 | + | |
550 | 538 | | |
551 | | - | |
| 539 | + | |
552 | 540 | | |
553 | 541 | | |
554 | 542 | | |
555 | | - | |
556 | | - | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
557 | 548 | | |
558 | 549 | | |
559 | 550 | | |
560 | | - | |
561 | | - | |
562 | | - | |
563 | | - | |
564 | | - | |
565 | | - | |
| 551 | + | |
566 | 552 | | |
567 | | - | |
| 553 | + | |
568 | 554 | | |
569 | 555 | | |
570 | | - | |
| 556 | + | |
571 | 557 | | |
572 | 558 | | |
573 | | - | |
| 559 | + | |
574 | 560 | | |
575 | 561 | | |
576 | 562 | | |
577 | 563 | | |
578 | | - | |
579 | | - | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
580 | 569 | | |
581 | 570 | | |
582 | 571 | | |
| |||
620 | 609 | | |
621 | 610 | | |
622 | 611 | | |
623 | | - | |
| 612 | + | |
624 | 613 | | |
625 | 614 | | |
626 | 615 | | |
| |||
714 | 703 | | |
715 | 704 | | |
716 | 705 | | |
717 | | - | |
718 | | - | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
719 | 709 | | |
720 | 710 | | |
721 | 711 | | |
| |||
731 | 721 | | |
732 | 722 | | |
733 | 723 | | |
734 | | - | |
| 724 | + | |
735 | 725 | | |
736 | 726 | | |
737 | 727 | | |
738 | | - | |
| 728 | + | |
739 | 729 | | |
740 | 730 | | |
741 | 731 | | |
742 | | - | |
| 732 | + | |
743 | 733 | | |
744 | 734 | | |
745 | 735 | | |
746 | | - | |
| 736 | + | |
747 | 737 | | |
748 | 738 | | |
749 | 739 | | |
| |||
757 | 747 | | |
758 | 748 | | |
759 | 749 | | |
760 | | - | |
761 | | - | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
762 | 753 | | |
763 | 754 | | |
764 | 755 | | |
| |||
774 | 765 | | |
775 | 766 | | |
776 | 767 | | |
777 | | - | |
| 768 | + | |
778 | 769 | | |
779 | 770 | | |
780 | 771 | | |
| |||
855 | 846 | | |
856 | 847 | | |
857 | 848 | | |
858 | | - | |
859 | | - | |
860 | | - | |
861 | | - | |
862 | | - | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
863 | 869 | | |
864 | 870 | | |
865 | 871 | | |
866 | 872 | | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
0 commit comments