KllItemsSketch: querying before serialization corrupts the round-tripped sorted view
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 76/100
Línea de trabajo
Comience con KllItemsSketch.CreateSortedView.getSV() y KllHeapItemsSketch.getTotalItemsArray(), y luego siga cómo KllHelper serializa el indicador level-zero-sorted y cómo heapify/wrap lo consumen. Reproduzca el caso proporcionado de un heap sketch de cuatro elementos, incluido wrap(), y compare las vistas ordenadas y los cuantiles originales con los obtenidos tras el round trip. Se considera terminado cuando consultar antes de la serialización ya no cambia los resultados tras el round trip.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Java
- Estrellas
- 958
- Forks
- 226
- Merge medio
- 3 d 40 min
- PR fusionados (30 d)
- 13
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de apache/datasketches-java
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
apache/datasketches-java#731 · 16 comentarios ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 58/100
apache/datasketches-java#739 · 1 comentario ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
apache/datasketches-java#720 · 3 comentarios ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
apache/datasketches-java#693 · 13 comentarios ·
-
Reservoir sampling improvements Abierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
apache/datasketches-java#647 · 5 comentarios ·
Todos los issues de apache/datasketches-java
Issues similares
-
certification
Dificultad 1/5 Menos de una hora Aptitud para principiantes 80/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
[BUG] ECR GetAuthorizationToken returns a proxyEndpoint for the default region, not the request's Abiertobug ecr
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Needs: Triage Type: Feature request
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
AntennaPod/AntennaPod#8794 ·
-
agentic-workflows
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
github/copilot-sdk#2760 ·