diff --git a/docs/changelog/126884.yaml b/docs/changelog/126884.yaml new file mode 100644 index 0000000000000..7ad905c93bf85 --- /dev/null +++ b/docs/changelog/126884.yaml @@ -0,0 +1,5 @@ +pr: 126884 +summary: Rare terms aggregation false **positive** fix +area: Aggregations +type: bug +issues: [] diff --git a/server/src/main/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilter.java b/server/src/main/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilter.java index 5ae3fb1ae8929..24c62e9e2aa9d 100644 --- a/server/src/main/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilter.java +++ b/server/src/main/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilter.java @@ -341,7 +341,7 @@ public void merge(SetBackedScalingCuckooFilter other) { } else if (isSetMode == false && other.isSetMode) { // Rather than converting the other to a cuckoo first, we can just // replay the values directly into our filter. - other.hashes.forEach(this::add); + other.hashes.forEach(this::addHash); } else { // Both are in cuckoo mode, merge raw fingerprints diff --git a/server/src/test/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilterTests.java b/server/src/test/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilterTests.java index 205dfeaa158c6..e69569d87e86e 100644 --- a/server/src/test/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilterTests.java +++ b/server/src/test/java/org/elasticsearch/common/util/SetBackedScalingCuckooFilterTests.java @@ -132,6 +132,34 @@ public void testConvertTwice() { ); } + public void testMergeBigSmall() { + int threshold = 1000; + + // Setup the first filter + SetBackedScalingCuckooFilter filter = new SetBackedScalingCuckooFilter(threshold, Randomness.get(), 0.01); + int counter = 0; + Set values = new HashSet<>(); + while (counter < threshold + 1) { + long value = randomLong(); + filter.add(value); + boolean newValue = values.add(value); + if (newValue) { + counter += 1; + } + } + + SetBackedScalingCuckooFilter filter2 = new SetBackedScalingCuckooFilter(threshold, Randomness.get(), 0.01); + long value = randomLong(); + while (filter.mightContain(value)) { + value = randomLong(); + } + + filter2.add(value); + + filter.merge(filter2); + assertTrue(filter.mightContain(value)); + } + public void testMergeSmall() { int threshold = 1000;