diff --git a/src/main/java/org/apache/datasketches/theta/JaccardSimilarity.java b/src/main/java/org/apache/datasketches/theta/JaccardSimilarity.java index 2fc9d4fe5..7f967198d 100644 --- a/src/main/java/org/apache/datasketches/theta/JaccardSimilarity.java +++ b/src/main/java/org/apache/datasketches/theta/JaccardSimilarity.java @@ -100,6 +100,10 @@ public static double[] jaccard(final ThetaSketch sketchA, final ThetaSketch sket /** * Returns true if the two given sketches have exactly the same hash values and the same * theta values. Thus, they are equivalent. + * + *

Note: For very large pairs of sketches, where the configured nominal entries of the sketches + * are 2^26, this method may return false even if the two sketches are equal. + * * @param sketchA the given sketch A * @param sketchB the given sketch B * @return true if the two given sketches have exactly the same hash values and the same @@ -116,8 +120,11 @@ public static boolean exactlyEqual(final ThetaSketch sketchA, final ThetaSketch final int countB = sketchB.getRetainedEntries(true); //Create the ThetaUnion + final int minK = 1 << ThetaUtil.MIN_LG_NOM_LONGS; + final int maxK = 1 << ThetaUtil.MAX_LG_NOM_LONGS; + final int newK = max(min(ceilingPowerOf2(countA + countB), maxK), minK); final ThetaUnion union = - ThetaSetOperation.builder().setNominalEntries(ceilingPowerOf2(countA + countB)).buildUnion(); + ThetaSetOperation.builder().setNominalEntries(newK).buildUnion(); union.union(sketchA); union.union(sketchB); final ThetaSketch unionAB = union.getResult(); diff --git a/src/test/java/org/apache/datasketches/theta/JaccardSimilarityTest.java b/src/test/java/org/apache/datasketches/theta/JaccardSimilarityTest.java index 4f84c5382..17cadcc92 100644 --- a/src/test/java/org/apache/datasketches/theta/JaccardSimilarityTest.java +++ b/src/test/java/org/apache/datasketches/theta/JaccardSimilarityTest.java @@ -233,6 +233,17 @@ public void checkMinK() { println(result[0] + ", " + result[1] + ", " + result[2]); } + @Test + public void checkMinKExactlyEqual() { + UpdatableThetaSketch skA = UpdatableThetaSketch.builder().build(); //4096 + UpdatableThetaSketch skB = UpdatableThetaSketch.builder().build(); //4096 + skA.update(1); + skB.update(1); + assertTrue(exactlyEqual(skA, skB)); + skB.update(2); + assertFalse(exactlyEqual(skA, skB)); + } + @Test public void printlnTest() { println("PRINTING: "+this.getClass().getName());