From a0b57e9fc237784f1605555513ec5b5e456b1f58 Mon Sep 17 00:00:00 2001 From: Lee Rhodes Date: Sat, 26 Sep 2026 14:16:59 -0700 Subject: [PATCH 1/4] Fix BloomFilterTest.basicDifferenceTest retention threshold With 8192 bits, right's load was ~46.5%, so only ~4.4% of left-only items could survive difference(), far below the test's 25% threshold. Raise numBits to 65536 (~7.5% load, ~68% expected retention). Co-Authored-By: Claude Opus 5.5 --- .../datasketches/filters/bloomfilter/BloomFilterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/apache/datasketches/filters/bloomfilter/BloomFilterTest.java b/src/test/java/org/apache/datasketches/filters/bloomfilter/BloomFilterTest.java index f5483d897..4b234202c 100644 --- a/src/test/java/org/apache/datasketches/filters/bloomfilter/BloomFilterTest.java +++ b/src/test/java/org/apache/datasketches/filters/bloomfilter/BloomFilterTest.java @@ -295,7 +295,7 @@ public void basicIntersectionTest() { @Test public void basicDifferenceTest() { - final long numBits = 8192; + final long numBits = 65536; // keeps right's load low (~7.5%) so most left-only items survive final int numHashes = 5; final BloomFilter left = BloomFilterBuilder.createBySize(numBits, numHashes); From 033178eafc8ce7759c42c101f11633a5d5330fbe Mon Sep 17 00:00:00 2001 From: Lee Rhodes Date: Sat, 26 Sep 2026 14:27:18 -0700 Subject: [PATCH 2/4] Fix pom so cross-language test groups are excluded by default The composite testng.* group properties were concatenated without commas, so surefire's excludedGroups only matched generate_java_files and check_java_files; C++/Go/Rust/CL-binary/historical groups ran on every 'mvn test'. Also point the check_CL_binary_files and check_cpp_historical_files profiles at the renamed properties. Co-Authored-By: Claude Opus 5.5 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index bdd818a48..40fa32fe6 100644 --- a/pom.xml +++ b/pom.xml @@ -146,9 +146,9 @@ under the License. ${testng.generate_java_files},${testng.check_java_files},${testng.check_cpp_files} ${testng.check_go_files},${testng.check_rust_files} - ${testng.check_CL_binaries}${testng.check_cpp_historicals} + ${testng.check_CL_binaries},${testng.check_cpp_historicals} - ${testng.check_java_cpp}${testng.check_go_rust}${testng.check_specials} + ${testng.check_java_cpp},${testng.check_go_rust},${testng.check_specials} ${project.basedir} false @@ -870,7 +870,7 @@ under the License. org.apache.maven.plugins maven-surefire-plugin - ${testng.check_CL_binary_files} + ${testng.check_CL_binaries} @@ -886,7 +886,7 @@ under the License. org.apache.maven.plugins maven-surefire-plugin - ${testng.check_cpp_historical_files} + ${testng.check_cpp_historicals} From 24e7b9367623d007fc74678eb5cdd1f4a8f2989b Mon Sep 17 00:00:00 2001 From: Lee Rhodes Date: Sat, 26 Sep 2026 14:27:18 -0700 Subject: [PATCH 3/4] Check TDigestDouble.merge weight overflow before touching min/max 9bf19ff6b moved the min/max update ahead of the Math.addExact check, so a merge that throws ArithmeticException still mutated the digest, failing weightOverflowDoesNotChangeDigest. Co-Authored-By: Claude Opus 5.5 --- .../java/org/apache/datasketches/tdigest/TDigestDouble.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/datasketches/tdigest/TDigestDouble.java b/src/main/java/org/apache/datasketches/tdigest/TDigestDouble.java index 4cd4169e0..fa99c3d99 100644 --- a/src/main/java/org/apache/datasketches/tdigest/TDigestDouble.java +++ b/src/main/java/org/apache/datasketches/tdigest/TDigestDouble.java @@ -117,10 +117,10 @@ public void update(final double value) { */ public void merge(final TDigestDouble other) { if (other.isEmpty()) { return; } + Math.addExact(getTotalWeight(), other.getTotalWeight()); // Extreme centroid means are not the true min/max when those centroids have weight > 1. minValue_ = Math.min(minValue_, other.minValue_); maxValue_ = Math.max(maxValue_, other.maxValue_); - Math.addExact(getTotalWeight(), other.getTotalWeight()); final int num = numCentroids_ + numBuffered_ + other.numCentroids_ + other.numBuffered_; final double[] values = new double[num]; final long[] weights = new long[num]; From 1481c3fc76bf78bf79a0d4a3edffba877911694b Mon Sep 17 00:00:00 2001 From: Lee Rhodes Date: Sat, 26 Sep 2026 16:16:47 -0700 Subject: [PATCH 4/4] CompactTupleSketch: write a zero seed hash for an empty image Follow the theta rule: a serialized empty compact sketch (8 bytes, preLongs = 1) carries a zero seed hash. C++ compact_tuple_sketch already does this, and no Java or C++ tuple reader checks the seed hash of an empty image, so this only brings the Java bytes in line with C++. Co-Authored-By: Claude Opus 5.5 --- .../java/org/apache/datasketches/tuple/CompactTupleSketch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/datasketches/tuple/CompactTupleSketch.java b/src/main/java/org/apache/datasketches/tuple/CompactTupleSketch.java index 030eae7e5..4c2ed8ef6 100644 --- a/src/main/java/org/apache/datasketches/tuple/CompactTupleSketch.java +++ b/src/main/java/org/apache/datasketches/tuple/CompactTupleSketch.java @@ -221,7 +221,7 @@ public byte[] toByteArray() { | (1 << Flags.IS_READ_ONLY.ordinal()) | (isEmpty() ? 1 << Flags.IS_EMPTY.ordinal() : 0) ); - ByteArrayUtil.putShortLE(bytes, offset, defaultSeedHash); + ByteArrayUtil.putShortLE(bytes, offset, isEmpty() ? 0 : defaultSeedHash); // empty image carries zero, as in theta offset += Short.BYTES; if (!isEmpty()) { if (!isSingleItem) {