Commit c448e34
committed
fix(client): make SF recovery segment sort O(N log N) unconditionally
sortByBaseSeq was a median-of-three Lomuto quicksort. Median-of-three
covers the readdir orders a healthy slot produces (lexicographic
enumeration yields already-sorted baseSeqs, hashed directory order is
effectively random), but Lomuto partitioning is O(N^2) on organ-pipe,
duplicate-heavy and median-of-three-killer orders. Exact simulation at
the documented 16K-segment ceiling: 22.6M comparisons for organ-pipe,
50.7M for Musser's med3-killer permutation, 134M (full N^2/2) for
mass-duplicate baseSeqs -- versus ~221K on the healthy paths. Such
orders are only reachable through corrupted-yet-parseable or
operator-copied headers, and recovery validation rejects those slots --
but the quadratic stall lands BEFORE validation gets to reject them.
The sort is now an introsort: the median-of-three fast path is
unchanged, and each root-to-leaf partition path carries a budget of
2*floor(log2(N)) passes. Loop-on-larger iterations count against the
budget, so bad-split chains cannot hide in the loop. Ranges that
exhaust it fall back to in-place heapsort (still Long.compareUnsigned,
zero allocation), capping every adversarial pattern at ~3.8*N*log2(N)
comparisons (organ-pipe 773K, duplicates 507K, med3-killer 861K at
N=16384). Recursion depth stays under log2(N).
The sortComparisons counter ticks +2 per sift-down level so it remains
a strict upper bound in the fallback. New adversarial test drives the
sort directly with in-memory segments at N=16384 across organ-pipe,
all-duplicate, few-distinct, med3-killer and sign-bit-key patterns,
asserting unsigned order plus comparisons < 8*N*log2(N) -- >2x headroom
over the worst measured pattern, ~12x below the mildest quadratic
blow-up. The existing sorted-input regression test is unchanged and
still passes.1 parent d130f2c commit c448e34
2 files changed
Lines changed: 186 additions & 14 deletions
File tree
- core/src
- main/java/io/questdb/client/cutlass/qwp/client/sf/cursor
- test/java/io/questdb/client/test/cutlass/qwp/client/sf/cursor
Lines changed: 91 additions & 14 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
74 | | - | |
75 | | - | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
76 | 77 | | |
77 | 78 | | |
78 | 79 | | |
| |||
1110 | 1111 | | |
1111 | 1112 | | |
1112 | 1113 | | |
1113 | | - | |
1114 | | - | |
1115 | | - | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
1116 | 1118 | | |
1117 | 1119 | | |
1118 | 1120 | | |
| |||
1145 | 1147 | | |
1146 | 1148 | | |
1147 | 1149 | | |
1148 | | - | |
1149 | | - | |
1150 | | - | |
1151 | | - | |
1152 | | - | |
1153 | | - | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
| 1174 | + | |
| 1175 | + | |
1154 | 1176 | | |
1155 | 1177 | | |
| 1178 | + | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
1156 | 1185 | | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
1157 | 1190 | | |
1158 | 1191 | | |
1159 | 1192 | | |
| |||
1183 | 1216 | | |
1184 | 1217 | | |
1185 | 1218 | | |
1186 | | - | |
| 1219 | + | |
| 1220 | + | |
| 1221 | + | |
| 1222 | + | |
1187 | 1223 | | |
1188 | | - | |
| 1224 | + | |
1189 | 1225 | | |
1190 | 1226 | | |
1191 | | - | |
| 1227 | + | |
1192 | 1228 | | |
1193 | 1229 | | |
1194 | 1230 | | |
1195 | 1231 | | |
1196 | 1232 | | |
| 1233 | + | |
| 1234 | + | |
| 1235 | + | |
| 1236 | + | |
| 1237 | + | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
| 1251 | + | |
| 1252 | + | |
| 1253 | + | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + | |
| 1272 | + | |
| 1273 | + | |
1197 | 1274 | | |
1198 | 1275 | | |
1199 | 1276 | | |
| |||
Lines changed: 95 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
686 | 686 | | |
687 | 687 | | |
688 | 688 | | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
689 | 784 | | |
690 | 785 | | |
691 | 786 | | |
| |||
0 commit comments