sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1733834 - in /sis/branches/JDK8/storage/sis-storage/src: main/java/org/apache/sis/internal/storage/ test/java/org/apache/sis/internal/storage/ test/java/org/apache/sis/test/suite/
Date Sun, 06 Mar 2016 19:55:54 GMT
Author: desruisseaux
Date: Sun Mar  6 19:55:54 2016
New Revision: 1733834

URL: http://svn.apache.org/viewvc?rev=1733834&view=rev
Log:
Add a HyperRectangleReader as an internal helper class for NetCDF, uncompressed GeoTIFF and
some other raster formats.

Added:
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
  (with props)
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
  (with props)
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
  (with props)
Modified:
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java

Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java?rev=1733834&r1=1733833&r2=1733834&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -602,6 +602,12 @@ public class ChannelDataInput extends Ch
             if (view == null) {
                 view = createView();                                    // Must be after
ensureBufferContains(int).
             } else {
+                // Buffer position must be a multiple of the data size.
+                // If not, fix that by shifting the content to index 0.
+                if ((buffer.position() & ((1 << dataSizeShift) - 1)) != 0) {
+                    bufferOffset += buffer.position();
+                    buffer.compact().flip();
+                }
                 view.limit   (buffer.limit()    >> dataSizeShift)
                     .position(buffer.position() >> dataSizeShift);      // See assumption
documented in Javadoc.
             }

Added: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java?rev=1733834&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
(added)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.internal.storage;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import org.apache.sis.util.Numbers;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.storage.DataStoreException;
+
+
+/**
+ * Helper methods for reading a rectangular area, a cube or a hyper-cube from a channel.
+ * The data can be stored in an existing array, or a new array can be created.
+ * This class does not handle compression; it is rather designed for efficient reading of
uncompressed data.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public final class HyperRectangleReader {
+    /**
+     * The channel from which to read the values, together with a buffer for transferring
data.
+     */
+    private final ChannelDataInput.ArrayReader reader;
+
+    /**
+     * The {@link #input} position of the first sample (ignoring sub-area and sub-sampling).
+     */
+    private final long origin;
+
+    /**
+     * Creates a new reader for the given input and source region.
+     *
+     * @param  dataType The type of elements to read, as one of the constants defined in
{@link Numbers}.
+     * @param  input The channel from which to read the values, together with a buffer for
transferring data.
+     * @param  origin The position in the channel of the first sample value in the hyper-rectangle.
+     * @throws DataStoreException if the given {@code dataType} is not one of the supported
values.
+     */
+    public HyperRectangleReader(final byte dataType, final ChannelDataInput input, final
long origin)
+            throws DataStoreException
+    {
+        switch (dataType) {
+            case Numbers.CHARACTER: reader = input.new CharsReader  (null); break;
+            case Numbers.SHORT:     reader = input.new ShortsReader (null); break;
+            case Numbers.INTEGER:   reader = input.new IntsReader   (null); break;
+            case Numbers.LONG:      reader = input.new LongsReader  (null); break;
+            case Numbers.FLOAT:     reader = input.new FloatsReader (null); break;
+            case Numbers.DOUBLE:    reader = input.new DoublesReader(null); break;
+            default: throw new DataStoreException(Errors.format(Errors.Keys.UnknownType_1,
dataType));
+        }
+        this.origin = origin;
+        final ByteBuffer buffer = input.buffer;
+        final int pos = buffer.position();
+        final int lim = buffer.limit();
+        try {
+            buffer.position(0).limit(buffer.capacity());
+            reader.createView();
+        } finally {
+            buffer.limit(lim).position(pos);
+        }
+    }
+
+    /**
+     * Returns the data input specified at construction time.
+     *
+     * @return The input channel together with the buffer.
+     */
+    public final ChannelDataInput input() {
+        return reader.input();
+    }
+
+    /**
+     * Reads data in the given region. It is caller's responsibility to ensure that the {@code
Region}
+     * object has been created with a {@code size} argument equals to this hyper-rectangle
size.
+     *
+     * @param  region The sub-area to read and the sub-sampling to use.
+     * @return The data in an array of primitive type.
+     * @throws IOException if an error occurred while transferring data from the channel.
+     */
+    public Object read(final Region region) throws IOException {
+        final int contiguousDataLength = region.targetLength(region.contiguousDataDimension);
+        final long[] strides = new long[region.getDimension() - region.contiguousDataDimension];
+        final int[]   cursor = new int[strides.length];
+        final int  sizeShift = reader.dataSizeShift();
+        long  streamPosition = origin + (region.startAt << sizeShift);
+        int    arrayPosition = 0;
+        for (int i=0; i<strides.length; i++) {
+            strides[i] = (region.skips[i + region.contiguousDataDimension] + contiguousDataLength)
<< sizeShift;
+            assert (strides[i] > 0) : i;
+        }
+        try {
+            reader.createDataArray(region.targetLength(region.getDimension()));
+            final ChannelDataInput input = reader.input();
+            final Buffer view = reader.view();
+loop:       do {
+                input.seek(streamPosition);
+                assert reader.view() == view;
+                reader.readFully(view, arrayPosition, contiguousDataLength);
+                for (int i=0; i<cursor.length; i++) {
+                    /*
+                     * After we have read as much contiguous data as we can (may be a row,
or a plane, or
+                     * a cube, etc. depending if we have to skip values or not between rows/planes/cubes),
+                     * search the highest dimension which is going to change (i.e. are we
going to start a
+                     * new row, or a new plane, or a new cube?). This determine how many
bytes we have to
+                     * skip.
+                     */
+                    if (++cursor[i] < region.targetSize[region.contiguousDataDimension
+ i]) {
+                        streamPosition += strides[i];
+                        arrayPosition  += contiguousDataLength;
+                        continue loop;
+                    }
+                    cursor[i] = 0;
+                }
+                break;
+            } while (true);
+            return reader.dataArray();
+        } finally {
+            reader.setDest(null);
+        }
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/HyperRectangleReader.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java?rev=1733834&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
(added)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.internal.storage;
+
+
+/**
+ * A sub-area in a <var>n</var>-dimensional hyper-rectangle, optionally with
sub-sampling.
+ * The size of the hyper-rectangle is given by the {@code size} argument at construction
time,
+ * where {@code size.length} is the number of dimensions and {@code size[i]} is the number
of
+ * values along dimension <var>i</var>. For each dimension, the index ranges
from 0 inclusive
+ * to {@code size[i]} exclusive.
+ *
+ * <p>This class assumes that the values are stored in a sequence (array or uncompressed
file)
+ * where index at dimension 0 varies fastest, followed by index at dimension 1, <i>etc</i>.</p>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public final class Region {
+    /**
+     * Total length of the sequence of values, ignoring sub-area and sub-sampling.
+     */
+    final long sourceLength;
+
+    /**
+     * The size after reading only the sub-region at the given sub-sampling.
+     * The length of this array is the hyper-rectangle dimension.
+     *
+     * @see #targetLength(int)
+     */
+    final int[] targetSize;
+
+    /**
+     * Position of the first value to read.
+     * This position is zero if the value of all {@code regionLower} elements is zero.
+     */
+    final long startAt;
+
+    /**
+     * Number of values to skip after having read a values.
+     *
+     * <ol>
+     *   <li>{@code skips[0]} is the number of values to skip after each single value
on the same line.</li>
+     *   <li>{@code skips[1]} is the number of values to skip after having read the
last value in a line.</li>
+     *   <li>{@code skips[2]} is the number of values to skip after having read the
last value in a plane.</li>
+     *   <li>{@code skips[3]} is the number of values to skip after having read the
last value in a cube.</li>
+     *   <li><i>etc.</i></li>
+     * </ol>
+     *
+     * The length of this array is the hyper-rectangle dimension plus one.
+     */
+    final long[] skips;
+
+    /**
+     * Number of dimensions for which we can collapse the read operations in a single operation
because their
+     * data are contiguous. This is the index of the first non-zero element in the {@link
#skips} array.
+     */
+    final int contiguousDataDimension;
+
+    /**
+     * Creates a new region. It is caller's responsibility to ensure that:
+     * <ul>
+     *   <li>all arrays have the same length</li>
+     *   <li>{@code size[i] > 0} for all <var>i</var></li>
+     *   <li>{@code regionLower[i] >= 0} for all <var>i</var></li>
+     *   <li>{@code regionLower[i] < regionUpper[i] <= size[i]} for all <var>i</var></li>
+     *   <li>{@code subsamplings[i] > 0} for all <var>i</var></li>
+     * </ul>
+     *
+     * @param size         The number of elements along each dimension.
+     * @param regionLower  Index of the first value to read or write along each dimension.
+     * @param regionUpper  Index after the last value to read or write along each dimension.
+     * @param subsamplings Sub-sampling along each dimension. Shall be greater than zero.
+     */
+    public Region(final long[] size, final long[] regionLower, final long[] regionUpper,
final int[] subsamplings) {
+        final int dimension = size.length;
+        targetSize = new int[dimension];
+        skips = new long[dimension + 1];
+        long position = 0;
+        long stride   = 1;
+        long skip     = 0;
+        for (int i=0; i<dimension;) {
+            final int  step  =  subsamplings[i];
+            final long lower =  regionLower [i];
+            final long count = (regionUpper [i] - lower + (step-1)) / step;      // (upper-lower)/step
rounded toward up, provided all values are positive.
+            final long upper = lower + ((count-1) * step + 1);
+            final long span  = size[i];
+            assert (count > 0) && (lower >= 0) && (upper > lower)
&& (upper <= span) : i;
+            targetSize[i] = Math.toIntExact(count);
+
+            position += stride * lower;
+            skip     += stride * (span - (upper - lower));
+            skips[i] += stride * (step - 1);
+            stride   *= span;
+            skips[++i] = skip;
+        }
+        startAt = position;
+        sourceLength = stride;
+        int i;
+        for (i=0; i<dimension; i++) {
+            if (skips[i] != 0) break;
+        }
+        contiguousDataDimension = i;
+    }
+
+    /**
+     * Returns the number of dimension.
+     *
+     * @return The hyper-rectangle dimension.
+     */
+    public final int getDimension() {
+        return targetSize.length;
+    }
+
+    /**
+     * Returns the total number of values to be read from the sub-region while applying the
sub-sampling.
+     * This method takes in account only the given number of dimensions.
+     */
+    final int targetLength(final int dimension) {
+        long length = 1;
+        for (int i=0; i<dimension; i++) {
+            length *= targetSize[i];
+        }
+        return Math.toIntExact(length);
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Region.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java?rev=1733834&r1=1733833&r2=1733834&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -32,7 +32,7 @@ import java.nio.channels.SeekableByteCha
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.7
  * @module
  *
  * @see ChannelDataOutputTest
@@ -64,9 +64,14 @@ final strictfp class ByteArrayChannel im
      * Creates a channel which will store all written data in the given array.
      *
      * @param data Bytes array where to write the data. The length of this array is the capacity.
+     * @param isContentValid {@code true} if the channel should be initialized with all the
{@code data} elements,
+     *        or {@code false} if the channel should be considered initially empty.
      */
-    ByteArrayChannel(final byte[] data) {
+    ByteArrayChannel(final byte[] data, final boolean isDataValid) {
         this.data = data;
+        if (isDataValid) {
+            limit = data.length;
+        }
     }
 
     /**
@@ -80,6 +85,7 @@ final strictfp class ByteArrayChannel im
         }
         final int length = StrictMath.min(dst.remaining(), limit - position);
         dst.put(data, position, length);
+        position += length;
         return length;
     }
 

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java?rev=1733834&r1=1733833&r2=1733834&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -82,7 +82,7 @@ public strictfp class ChannelDataOutputT
         referenceStream          = new DataOutputStream(expectedData);
         testedStreamBackingArray = new byte[streamLength];
         testedStream             = new ChannelDataOutput(testName,
-                new ByteArrayChannel(testedStreamBackingArray), ByteBuffer.allocate(bufferLength));
+                new ByteArrayChannel(testedStreamBackingArray, false), ByteBuffer.allocate(bufferLength));
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java?rev=1733834&r1=1733833&r2=1733834&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelImageOutputStreamTest.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -48,7 +48,7 @@ public final strictfp class ChannelImage
         referenceStream          = new MemoryCacheImageOutputStream(expectedData);
         testedStreamBackingArray = new byte[streamLength];
         testedStream             = new ChannelImageOutputStream(fileName,
-                new ByteArrayChannel(testedStreamBackingArray), ByteBuffer.allocate(bufferLength));
+                new ByteArrayChannel(testedStreamBackingArray, false), ByteBuffer.allocate(bufferLength));
     }
 
     /**

Added: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java?rev=1733834&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
(added)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.internal.storage;
+
+import java.util.Arrays;
+import java.util.Random;
+import java.nio.ByteOrder;
+import java.nio.ByteBuffer;
+import java.nio.ShortBuffer;
+import java.io.IOException;
+import org.apache.sis.util.Numbers;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.apache.sis.test.TestUtilities;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests {@link HyperRectangleReader}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+@DependsOn(ChannelDataInputTest.class)
+public final strictfp class HyperRectangleReaderTest extends TestCase {
+    /**
+     * The hyper-cube dimensions.
+     */
+    private final long[] size = new long[4];
+
+    /**
+     * Lower values of the sub-region to test.
+     */
+    private final long[] lower = new long[size.length];
+
+    /**
+     * Upper values of the sub-region to test.
+     */
+    private final long[] upper = new long[size.length];
+
+    /**
+     * Sub-sampling values to use for the test.
+     */
+    private final int[] subsampling = new int[size.length];
+
+    /**
+     * The reader to test for an hyper-cube of {@code short} values, created by {@link #initialize(Random)}.
+     * Sample values are index values encoded in base 10. For example the value at index
(4,1,2,3) will be 4123.
+     */
+    private HyperRectangleReader reader;
+
+    /**
+     * Encodes the given index in the sample values to be stored in the array of data.
+     * We use a decimal encoding for making easier to compare the actual values with the
expected ones.
+     */
+    private static long sampleValue(final long i0, final long i1, final long i2, final long
i3) {
+        return i3*1000 + i2*100 + i1*10 + i0;
+    }
+
+    /**
+     * Creates an hyper-rectangle of random size and initializes the sub-region and sub-sampling
to random values.
+     * Sample values are index values encoded in base 10. For example the value at index
(4,1,2,3) will be 4123.
+     *
+     * @param random The random number generator to use for initializing the test.
+     */
+    private void initialize(final Random random) throws IOException, DataStoreException {
+        /*
+         * Compute a random hyper-rectangle size, sub-region and sub-sampling. Each dimension
will have a
+         * size between 1 to 10, so we will be able to use decimal digits from 0 to 9 in
the sample values.
+         */
+        int length = 1;
+        for (int i=0; i<size.length; i++) {
+            final int s = random.nextInt(9) + 1;
+            int low = random.nextInt(s);
+            int up  = random.nextInt(s);
+            if (low > up) {
+                final int t = low;
+                low = up; up = t;
+            }
+            size [i] = s;
+            lower[i] = low;
+            upper[i] = up + 1;
+            subsampling[i] = random.nextInt(3) + 1;
+            length *= s;
+        }
+        /*
+         * Prepare an array of bytes which will contain the short values using native byte
order.
+         * Put small amout of random value at the array beginning in order to test with an
origin
+         * different than zero.
+         */
+        final int origin = random.nextInt(10);
+        final byte[] array = new byte[origin + length*Short.BYTES];
+        for (int i=0; i<origin; i++) {
+            array[i] = (byte) random.nextInt(0x100);
+        }
+        /*
+         * Fill the array with short values using the encoding describes in javadoc.
+         * Then wrap the array in a pseudo-channel so we can create the reader to test.
+         */
+        ShortBuffer view = ByteBuffer.wrap(array, origin, length*Short.BYTES).order(ByteOrder.nativeOrder()).asShortBuffer();
+        for (int i3=0; i3<size[3]; i3++) {
+            for (int i2=0; i2<size[2]; i2++) {
+                for (int i1=0; i1<size[1]; i1++) {
+                    for (int i0=0; i0<size[0]; i0++) {
+                        view.put((short) sampleValue(i0, i1, i2, i3));
+                    }
+                }
+            }
+        }
+        assertEquals(length, view.position());
+        final ByteArrayChannel channel = new ByteArrayChannel(array, true);
+        final ByteBuffer       buffer  = ByteBuffer.allocate(random.nextInt(20) + 20).order(ByteOrder.nativeOrder());
+        final ChannelDataInput input   = new ChannelDataInput("HyperRectangle", channel,
buffer, false);
+        reader = new HyperRectangleReader(Numbers.SHORT, input, origin);
+    }
+
+    /**
+     * Extracts data from a region defined by current {@link #lower}, {@link #upper} and
{@link #subsampling} values,
+     * then compares against the expected values.
+     */
+    private void verifyRegionRead() throws IOException {
+        final short[] data = (short[]) reader.read(new Region(size, lower, upper, subsampling));
+        int p = 0;
+        final int s3 = subsampling[3];
+        final int s2 = subsampling[2];
+        final int s1 = subsampling[1];
+        final int s0 = subsampling[0];
+        for (long i3=lower[3]; i3<upper[3]; i3 += s3) {
+            for (long i2=lower[2]; i2<upper[2]; i2 += s2) {
+                for (long i1=lower[1]; i1<upper[1]; i1 += s1) {
+                    for (long i0=lower[0]; i0<upper[0]; i0 += s0) {
+                        assertEquals("Sample value", sampleValue(i0, i1, i2, i3), data[p++]);
+                    }
+                }
+            }
+        }
+        assertEquals("Array length", p, data.length);
+    }
+
+    /**
+     * Tests reading a random part of the hyper-cube without sub-sampling.
+     *
+     * @throws IOException should never happen.
+     * @throws DataStoreException should never happen.
+     */
+    @Test
+    public void testSubRegion() throws IOException, DataStoreException {
+        initialize(TestUtilities.createRandomNumberGenerator());
+        Arrays.fill(subsampling, 0, subsampling.length, 1);
+        verifyRegionRead();
+    }
+
+    /**
+     * Tests reading the full hyper-cube with a random sub-sampling.
+     *
+     * @throws IOException should never happen.
+     * @throws DataStoreException should never happen.
+     */
+    @Test
+    public void testSubSampling() throws IOException, DataStoreException {
+        initialize(TestUtilities.createRandomNumberGenerator());
+        System.arraycopy(size, 0, upper, 0, size.length);
+        Arrays.fill(lower, 0, lower.length, 0);
+        verifyRegionRead();
+    }
+
+    /**
+     * Tests reading a random part of the hyper-cube with a random sub-sampling.
+     *
+     * @throws IOException should never happen.
+     * @throws DataStoreException should never happen.
+     */
+    @Test
+    @DependsOnMethod({"testSubRegion", "testSubSampling"})
+    public void testRandom() throws IOException, DataStoreException {
+        initialize(TestUtilities.createRandomNumberGenerator());
+        verifyRegionRead();
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/HyperRectangleReaderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java?rev=1733834&r1=1733833&r2=1733834&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
[UTF-8] Sun Mar  6 19:55:54 2016
@@ -35,6 +35,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.storage.ChannelDataOutputTest.class,
     org.apache.sis.internal.storage.ChannelImageInputStreamTest.class,
     org.apache.sis.internal.storage.ChannelImageOutputStreamTest.class,
+    org.apache.sis.internal.storage.HyperRectangleReaderTest.class,
     org.apache.sis.storage.ProbeResultTest.class,
     org.apache.sis.storage.StorageConnectorTest.class,
     org.apache.sis.internal.storage.xml.MimeTypeDetectorTest.class,



Mime
View raw message