From 58440059abb38eef7216ed79c2ced2a489aca979 Mon Sep 17 00:00:00 2001 From: Shailesh Singh Date: Thu, 30 Jan 2025 17:53:14 +0530 Subject: [PATCH] Fix Bug - handle unsigned long in assertion of LongHashSet Signed-off-by: Shailesh Singh --- .../org/apache/lucene/util/LongHashSet.java | 18 +++++++++++++++--- .../SortedUnsignedLongDocValuesSetQuery.java | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/org/apache/lucene/util/LongHashSet.java b/server/src/main/java/org/apache/lucene/util/LongHashSet.java index a463e8a189585..ec706b1cd6526 100644 --- a/server/src/main/java/org/apache/lucene/util/LongHashSet.java +++ b/server/src/main/java/org/apache/lucene/util/LongHashSet.java @@ -30,8 +30,12 @@ public final class LongHashSet implements Accountable { /** maximum value in the set, or Long.MIN_VALUE for an empty set */ public final long maxValue; - /** Construct a set. Values must be in sorted order. */ public LongHashSet(long[] values) { + this(values, false); + } + + /** Construct a set. Values must be in sorted order. */ + public LongHashSet(long[] values, boolean isUnsignedLong) { int tableSize = Math.toIntExact(values.length * 3L / 2); tableSize = 1 << PackedInts.bitsRequired(tableSize); // make it a power of 2 assert tableSize >= values.length * 3L / 2; @@ -40,7 +44,7 @@ public LongHashSet(long[] values) { mask = tableSize - 1; boolean hasMissingValue = false; int size = 0; - long previousValue = Long.MIN_VALUE; // for assert + long previousValue = isUnsignedLong ? 0 : Long.MIN_VALUE; // for assert for (long value : values) { if (value == MISSING) { size += hasMissingValue ? 0 : 1; @@ -48,7 +52,7 @@ public LongHashSet(long[] values) { } else if (add(value)) { ++size; } - assert value >= previousValue : "values must be provided in sorted order"; + assertBasedOnDataType(value, previousValue, isUnsignedLong); previousValue = value; } this.hasMissingValue = hasMissingValue; @@ -57,6 +61,14 @@ public LongHashSet(long[] values) { this.maxValue = values.length == 0 ? Long.MIN_VALUE : values[values.length - 1]; } + private void assertBasedOnDataType(long value, long previousValue, boolean isUnsignedLong) { + if (isUnsignedLong) { + assert Long.compareUnsigned(value, previousValue) >= 0 : "values must be provided in sorted order"; + } else { + assert value >= previousValue : "values must be provided in sorted order"; + } + } + private boolean add(long l) { assert l != MISSING; final int slot = Long.hashCode(l) & mask; diff --git a/server/src/main/java/org/opensearch/index/document/SortedUnsignedLongDocValuesSetQuery.java b/server/src/main/java/org/opensearch/index/document/SortedUnsignedLongDocValuesSetQuery.java index 7f4f47054207e..48f9fc046f4e5 100644 --- a/server/src/main/java/org/opensearch/index/document/SortedUnsignedLongDocValuesSetQuery.java +++ b/server/src/main/java/org/opensearch/index/document/SortedUnsignedLongDocValuesSetQuery.java @@ -45,7 +45,7 @@ public abstract class SortedUnsignedLongDocValuesSetQuery extends Query { SortedUnsignedLongDocValuesSetQuery(String field, BigInteger[] numbers) { this.field = Objects.requireNonNull(field); Arrays.sort(numbers); - this.numbers = new LongHashSet(Arrays.stream(numbers).mapToLong(n -> n.longValue()).toArray()); + this.numbers = new LongHashSet(Arrays.stream(numbers).mapToLong(n -> n.longValue()).toArray(), true); } @Override