Repository: hazelcast/hazelcast (language: java)

Issue:
Remove redundant backported Java 8 code in `com.hazelcast.query.impl.bitmap.BitmapUtils`
`com.hazelcast.query.impl.bitmap.BitmapUtils` contains some `.toUnsigned` methods that are backports of the Java 8 implementation.

This was originally implemented in commit [47e56665164a448973fe112db923788a5aa8130a](https://github.com/hazelcast/hazelcast/pull/16162/commits/47e56665164a448973fe112db923788a5aa8130a), when at the time, the destination [hazelcast:maintenance-3.x](https://github.com/hazelcast/hazelcast/tree/maintenance-3.x) branch was [on Java 6](https://github.com/taburet/hazelcast/blob/47e56665164a448973fe112db923788a5aa8130a/pom.xml).

But now Hazelcast is running on at least Java 11, so this backport is no longer required - and instead it should use the native methods.


Discussion / hints:

Fix patch:
diff --git a/hazelcast/src/main/java/com/hazelcast/query/impl/bitmap/BitmapUtils.java b/hazelcast/src/main/java/com/hazelcast/query/impl/bitmap/BitmapUtils.java
index dc4ecd02d9079..b4426e693cbf1 100644
--- a/hazelcast/src/main/java/com/hazelcast/query/impl/bitmap/BitmapUtils.java
+++ b/hazelcast/src/main/java/com/hazelcast/query/impl/bitmap/BitmapUtils.java
@@ -21,10 +21,6 @@
  */
 final class BitmapUtils {
 
-    private static final int SHORT_TO_INT_MASK = 0xFFFF;
-    private static final long SHORT_TO_LONG_MASK = 0xFFFFL;
-    private static final long INT_TO_LONG_MASK = 0xFFFFFFFFL;
-
     private static final int INT_ARRAY_MIN_CAPACITY = 2;
     private static final int SHORT_ARRAY_MIN_CAPACITY = 4;
 
@@ -39,25 +35,19 @@ final class BitmapUtils {
     private BitmapUtils() {
     }
 
-    /**
-     * Does exactly the same thing as Java 8 Short.toUnsignedInt.
-     */
+    /** @see Short#toUnsignedInt(short) */
     public static int toUnsignedInt(short value) {
-        return ((int) value) & SHORT_TO_INT_MASK;
+        return Short.toUnsignedInt(value);
     }
 
-    /**
-     * Does exactly the same thing as Java 8 Short.toUnsignedLong.
-     */
+    /** @see Short#toUnsignedLong(short) */
     public static long toUnsignedLong(short value) {
-        return ((long) value) & SHORT_TO_LONG_MASK;
+        return Short.toUnsignedLong(value);
     }
 
-    /**
-     * Does exactly the same thing as Java 8 Integer.toUnsignedLong.
-     */
+    /** @see Integer#toUnsignedLong(short) */
     public static long toUnsignedLong(int value) {
-        return ((long) value) & INT_TO_LONG_MASK;
+        return Integer.toUnsignedLong(value);
     }
 
     /**


Test patch:
diff --git a/hazelcast/src/test/java/com/hazelcast/query/impl/bitmap/BitmapUtilsTest.java b/hazelcast/src/test/java/com/hazelcast/query/impl/bitmap/BitmapUtilsTest.java
new file mode 100644
index 0000000000000..3974dcf7ec1c0
--- /dev/null
+++ b/hazelcast/src/test/java/com/hazelcast/query/impl/bitmap/BitmapUtilsTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2008-2023, Hazelcast, Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hazelcast.query.impl.bitmap;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import com.hazelcast.test.HazelcastParallelClassRunner;
+import com.hazelcast.test.annotation.ParallelJVMTest;
+import com.hazelcast.test.annotation.QuickTest;
+
+import java.util.stream.Stream;
+
+/**
+ * Assert that the new {@code toUnsigned} implementations return the same results as the previous implementations
+ *
+ * @see <a href="https://github.com/hazelcast/hazelcast/issues/25216">GitHub issue</a>
+ */
+@RunWith(HazelcastParallelClassRunner.class)
+@Category({QuickTest.class, ParallelJVMTest.class})
+public class BitmapUtilsTest {
+
+    private static int shortToIntMask;
+    private static long shortToLongMask;
+    private static long intToLongMask;
+
+    @BeforeClass
+    public static void setUp() {
+        shortToIntMask = 0xFFFF;
+        shortToLongMask = 0xFFFFL;
+        intToLongMask = 0xFFFFFFFFL;
+    }
+
+    @Test
+    public void testShortToUnsignedInt() {
+        getShortTestData().forEach(
+                val -> assertEquals(val.toString(), toUnsignedIntPreviousImplementation(val), BitmapUtils.toUnsignedInt(val)));
+    }
+
+    /**
+     * Does exactly the same thing as Java 8 Short.toUnsignedInt.
+     */
+    public static int toUnsignedIntPreviousImplementation(short value) {
+        return ((int) value) & shortToIntMask;
+    }
+
+    @Test
+    public void testShortToUnsignedLong() {
+        getShortTestData().forEach(val -> assertEquals(val.toString(), toUnsignedLongPreviousImplementation(val),
+                BitmapUtils.toUnsignedLong(val)));
+    }
+
+    /**
+     * Does exactly the same thing as Java 8 Short.toUnsignedLong.
+     */
+    public static long toUnsignedLongPreviousImplementation(short value) {
+        return ((long) value) & shortToLongMask;
+    }
+
+    @Test
+    public void testIntToUnsignedLong() {
+        getIntegerTestData().forEach(val -> assertEquals(val.toString(), toUnsignedLongPreviousImplementation(val),
+                BitmapUtils.toUnsignedLong(val)));
+    }
+
+    /**
+     * Does exactly the same thing as Java 8 Integer.toUnsignedLong.
+     */
+    public static long toUnsignedLongPreviousImplementation(int value) {
+        return ((long) value) & intToLongMask;
+    }
+
+    private static Stream<Short> getShortTestData() {
+        return Stream.of(Short.MIN_VALUE, (short) -1, (short) 0, (short) 1, Short.MAX_VALUE);
+    }
+
+    private static Stream<Integer> getIntegerTestData() {
+        return Stream.of(Integer.MIN_VALUE, (int) Short.MIN_VALUE, -1, 0, 1, (int) Short.MAX_VALUE, Integer.MAX_VALUE);
+    }
+}