KllItemsSketch: querying before serialization corrupts the round-tripped sorted view
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 76/100
Hướng nghiên cứu
Bắt đầu với KllItemsSketch.CreateSortedView.getSV() và KllHeapItemsSketch.getTotalItemsArray(), sau đó theo dõi cách KllHelper tuần tự hóa cờ level-zero-sorted và cách heapify/wrap sử dụng cờ này. Tái hiện trường hợp heap sketch bốn phần tử được cung cấp, bao gồm wrap(), rồi so sánh các chế độ xem đã sắp xếp và các phân vị ban đầu với các chế độ xem và phân vị sau round trip. Được xem là hoàn tất khi việc truy vấn trước khi tuần tự hóa không còn làm thay đổi kết quả sau round trip.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Querying a heap KllItemsSketch before serializing it makes the round-trip return wrong quantiles. The bytes are fine, the flag inside them is not.
KllItemsSketch<String> sk = KllItemsSketch.newHeapInstance(8, Comparator.naturalOrder(), new ArrayOfStringsSerDe());
sk.update("a"); sk.update("b"); sk.update("c"); sk.update("d");
sk.getQuantile(0.5, INCLUSIVE); // any query is enough
KllItemsSketch<String> rt = KllItemsSketch.heapify(
MemorySegment.ofArray(sk.toByteArray()), Comparator.naturalOrder(), serDe);
orig SV = [a, b, c, d]
heapified SV = [a, d, c, b, a, d]
rank=0.50 orig=b heapified=c
rank=0.55 orig=c heapified=b
Four items in, a six-element sorted view out, in raw insertion order with duplicated min and max. wrap() behaves the same. Without the query first there is no difference at all. At n=8, 15 of 21 probed ranks disagree.
KllItemsSketch.CreateSortedView.getSV() sorts level 0 and then records that it did:
final T[] srcQuantiles = getTotalItemsArray();
...
if (!isLevelZeroSorted()) {
Arrays.sort(srcQuantiles, srcLevelsArr[0], srcLevelsArr[1], comparator);
if (!hasMemorySegment()) { setLevelZeroSorted(true); }
}
For the heap items variant getTotalItemsArray() hands back a defensive copy (KllHeapItemsSketch:255-260 does a System.arraycopy), so the sort lands on the copy while the flag is set on the sketch. KllHelper then writes that flag into the serialized image and heapify/wrap trust it and skip the sort.
The doubles path does the same thing correctly because KllHeapDoublesSketch.getDoubleItemsArray() returns the live array, which is what makes the comment at KllDoublesSketch:562 true:
//we don't sort level0 in MemorySegment, only our copy.
So this looks specific to the generic Items variant rather than a design choice. Floats, Longs, Req and classic quantiles are all unaffected.
Live sketches recover on their own, because updateItem re-sorts level 0 and resets the flag, and I could not reproduce it through merge() in 30000 cases, so the damage seems confined to serializing a sketch that has been queried.
Either dropping the setLevelZeroSorted(true) here or returning the live array from KllHeapItemsSketch.getTotalItemsArray() would fix it. I did not send a patch because I have another PR open here (#755) and did not want two at once, but I am happy to put one up.
Found while fuzzing quantile invariants across the families: about 95000 randomized configurations over KllDoubles/Floats/Longs/Items, ReqSketch and classic quantiles, heap and direct, heapify and wrap, ten data distributions. This was the only invariant violation. Related but not the same as the closed #527, which was about which comparator level 0 is sorted with.
AI disclosure: I used Claude Code for the fuzzing harness and to narrow this down. I ran and checked the repro myself.
- Ngôn ngữ chính
- Java
- Star
- 958
- Fork
- 226
- Merge trung bình
- 3 ngày 40 phút
- Pull request đã merge (30 ngày)
- 13
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/datasketches-java
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
apache/datasketches-java#731 · 16 bình luận ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 58/100
apache/datasketches-java#739 · 1 bình luận ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
apache/datasketches-java#720 · 3 bình luận ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
apache/datasketches-java#693 · 13 bình luận ·
-
Reservoir sampling improvements Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
apache/datasketches-java#647 · 5 bình luận ·
Tất cả issue của apache/datasketches-java
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
infinispan/infinispan#18150 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
-
untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
opensearch-project/k-NN#3597 ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100