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 <[email protected]>
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