This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 38b7778  Add a constant for the number of bits in `Long.SIZE`. Used in 
bit shifts.
38b7778 is described below

commit 38b777853144c9f165be134611ff891d3a7ef385
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Nov 4 19:18:30 2021 +0100

    Add a constant for the number of bits in `Long.SIZE`. Used in bit shifts.
---
 .../java/org/apache/sis/image/MaskedImage.java     |  5 ++--
 .../java/org/apache/sis/index/tree/PointTree.java  |  3 ++-
 .../org/apache/sis/internal/util/Numerics.java     | 17 ++++++++++--
 .../java/org/apache/sis/util/CharSequences.java    |  2 +-
 .../apache/sis/util/collection/IntegerList.java    |  3 ++-
 .../org/apache/sis/internal/util/NumericsTest.java | 30 +++++++++++++++++++++-
 6 files changed, 52 insertions(+), 8 deletions(-)

diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java 
b/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java
index 9b4b3ec..63ec657 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/image/MaskedImage.java
@@ -39,6 +39,7 @@ import org.apache.sis.internal.coverage.j2d.ImageUtilities;
 import org.apache.sis.internal.coverage.j2d.TilePlaceholder;
 
 import static org.apache.sis.internal.util.Numerics.ceilDiv;
+import static org.apache.sis.internal.util.Numerics.LONG_SHIFT;
 
 
 /**
@@ -275,9 +276,9 @@ final class MaskedImage extends SourceAlignedImage {
          */
         for (int y=yStart; y<yEnd; y++) {
             int index = (y - maskBounds.y) * maskScanlineStride;    // Index 
in unit of bits for now (converted later).
-            final int emax  = (index +  imax) /  Long.SIZE;         // Last 
index in unit of long elements, inclusive.
+            final int emax  = (index +  imax) >>> LONG_SHIFT;       // Last 
index in unit of long elements, inclusive.
             final int shift = (index += xoff) & (Long.SIZE-1);      // First 
bit to read in the long, 0 = highest bit.
-            index /= Long.SIZE;                                     // Convert 
from bit (pixel) index to long[] index.
+            index >>>= LONG_SHIFT;                                  // Convert 
from bit (pixel) index to long[] index.
             /*
              * We want a value such as `base + index*Long.SIZE + lower` is 
equal to `xStart`
              * when all variables point to the first potentially masked pixel 
of the tile:
diff --git 
a/core/sis-feature/src/main/java/org/apache/sis/index/tree/PointTree.java 
b/core/sis-feature/src/main/java/org/apache/sis/index/tree/PointTree.java
index c1a672c..81e0d0e 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/index/tree/PointTree.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/index/tree/PointTree.java
@@ -27,6 +27,7 @@ import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.collection.CheckedContainer;
@@ -106,7 +107,7 @@ public class PointTree<E> extends AbstractSet<E> implements 
CheckedContainer<E>,
      * The maximum number of dimensions (inclusive) that this class currently 
supports.
      * Current maximum is {@value}. This restriction come from 2⁶ = {@value 
Long#SIZE}.
      */
-    public static final int MAXIMUM_DIMENSIONS = 6;
+    public static final int MAXIMUM_DIMENSIONS = Numerics.LONG_SHIFT;
 
     /**
      * The type of elements in this set.
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java 
b/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
index 5d18ba9..f986424 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
@@ -39,7 +39,7 @@ import static java.lang.Math.ulp;
  * Miscellaneous utilities methods working on floating point numbers.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.3
  * @module
  */
@@ -155,6 +155,19 @@ public final class Numerics extends Static {
     public static final int MAX_INTEGER_CONVERTIBLE_TO_FLOAT = 1 << 
(SIGNIFICAND_SIZE_OF_FLOAT + 1);
 
     /**
+     * Right shift to apply for a result equivalent to a division by 
{@Long#SIZE} (ignoring negative numbers).
+     * The value is {@value} so that the following relationship hold: 2⁶ = 
{@value Long#SIZE}.
+     *
+     * <h4>Usage</h4>
+     * The {@code x / Long.SIZE} operation can be replaced by {@code x >>> 
LONG_SHIFT} if <var>x</var> is positive.
+     * The compiler may not do this optimization itself because those two 
operations are not equivalent for negative
+     * <var>x</var> values (even with {@code >>} instead of {@code >>>}). By 
contrast it is not worth to apply such
+     * replacement on multiplications because the {@code x * Long.SIZE} and 
{@code x << LONG_SHIFT} operations are
+     * equivalent for all numbers (positive or negative), so the compiler is 
more likely to optimize itself.
+     */
+    public static final int LONG_SHIFT = 6;
+
+    /**
      * Do not allow instantiation of this class.
      */
     private Numerics() {
@@ -174,7 +187,7 @@ public final class Numerics extends Static {
      * @return a mask with the given bit set, or 0 if the given argument is 
negative or ≥ {@value Long#SIZE}.
      */
     public static long bitmask(final int bit) {
-        return (bit >= 0 && bit < Long.SIZE) ? (1L << bit) : 0;
+        return (bit & ~(Long.SIZE - 1)) == 0 ? (1L << bit) : 0;
     }
 
     /**
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java 
b/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
index 1da7c98..685cd0a 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
@@ -1094,7 +1094,7 @@ search:     for (; fromIndex <= toIndex; fromIndex++) {
             final int length = text.length();
             int toRemove = length - maxLength;
             if (toRemove > 0) {
-                toRemove += 5; // Space needed for the " (…) " string.
+                toRemove += 5;          // Space needed for the " (…) " string.
                 /*
                  * We will remove characters from 'lower' to 'upper' both 
exclusive. We try to
                  * adjust 'lower' and 'upper' in such a way that the first and 
last characters
diff --git 
a/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java
 
b/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java
index 9c9ab31..d073336 100644
--- 
a/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java
+++ 
b/core/sis-utility/src/main/java/org/apache/sis/util/collection/IntegerList.java
@@ -33,6 +33,7 @@ import java.io.ObjectOutputStream;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.jdk9.JDK9;
+import org.apache.sis.internal.util.Numerics;
 
 
 /**
@@ -65,7 +66,7 @@ public class IntegerList extends AbstractList<Integer> 
implements RandomAccess,
      * The shift to apply on {@code index} in order to produce a result 
equivalent to {@code index} / {@value #VALUE_SIZE}.
      * The following relation must hold: {@code (1 << BASE_SHIFT) == 
VALUE_SIZE}.
      */
-    private static final int BASE_SHIFT = 6;
+    private static final int BASE_SHIFT = Numerics.LONG_SHIFT;
 
     /**
      * The mask to apply on {@code index} in order to produce a result 
equivalent to {@code index} % {@value #VALUE_SIZE}.
diff --git 
a/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java 
b/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
index 3bced31..d6ec734 100644
--- 
a/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
+++ 
b/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
@@ -34,13 +34,41 @@ import static org.junit.Assert.*;
  * Tests the {@link Numerics} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.3
  * @module
  */
 @SuppressWarnings("UnnecessaryBoxing")
 public final strictfp class NumericsTest extends TestCase {
     /**
+     * Verifies the value of {@link Numerics#LONG_SHIFT}.
+     */
+    @Test
+    public void verifyMaxDimension() {
+        assertEquals(Long.SIZE, 1 << Numerics.LONG_SHIFT);
+        for (int i=350; i<400; i += 17) {
+            assertEquals(i / Long.SIZE, i >> Numerics.LONG_SHIFT);
+            assertEquals(i * Long.SIZE, i << Numerics.LONG_SHIFT);
+        }
+    }
+
+    /**
+     * Tests {@link Numerics#bitmask(int)}.
+     */
+    @Test
+    public void testBitmask() {
+        assertEquals( 1L, Numerics.bitmask(0));
+        assertEquals( 2L, Numerics.bitmask(1));
+        assertEquals(32L, Numerics.bitmask(5));
+        assertEquals(Long.SIZE, Numerics.bitmask(Numerics.LONG_SHIFT));
+        assertEquals(Long.MIN_VALUE, Numerics.bitmask(Long.SIZE - 1));
+        assertEquals( 0L, Numerics.bitmask(Long.SIZE));
+        assertEquals( 0L, Numerics.bitmask(100));
+        assertEquals( 0L, Numerics.bitmask(-1));
+        assertEquals( 0L, Numerics.bitmask(-256));
+    }
+
+    /**
      * Tests {@link Numerics#ceilDiv(int, int)} and {@link 
Numerics#ceilDiv(long, long)}.
      */
     @Test

Reply via email to