From ff2ec4c8e2b7bf1189b98fbeaf80ca85ff37862f Mon Sep 17 00:00:00 2001 From: Matteo Di Giovinazzo Date: Sat, 18 Apr 2020 23:42:22 -0600 Subject: [PATCH] #391 Move out `Index` as an interface and separate a `DefaultIndex` and a `CustomStridesIndex` to keep the previous logic --- .../javacpp/indexer/CustomStridesIndex.java | 76 +++++++++++++++++++ .../javacpp/indexer/DefaultIndex.java | 51 +++++++++++++ .../org/bytedeco/javacpp/indexer/Index.java | 66 ++++++++++++++++ .../org/bytedeco/javacpp/indexer/Indexer.java | 75 ++++++++---------- .../org/bytedeco/javacpp/IndexerTest.java | 5 +- 5 files changed, 228 insertions(+), 45 deletions(-) create mode 100644 src/main/java/org/bytedeco/javacpp/indexer/CustomStridesIndex.java create mode 100644 src/main/java/org/bytedeco/javacpp/indexer/DefaultIndex.java create mode 100644 src/main/java/org/bytedeco/javacpp/indexer/Index.java diff --git a/src/main/java/org/bytedeco/javacpp/indexer/CustomStridesIndex.java b/src/main/java/org/bytedeco/javacpp/indexer/CustomStridesIndex.java new file mode 100644 index 000000000..c0825cb97 --- /dev/null +++ b/src/main/java/org/bytedeco/javacpp/indexer/CustomStridesIndex.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016-2019 Samuel Audet + * + * Licensed either under the Apache License, Version 2.0, or (at your option) + * under the terms of the GNU General Public License as published by + * the Free Software Foundation (subject to the "Classpath" exception), + * either version 2, or any later version (collectively, 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 + * http://www.gnu.org/licenses/ + * http://www.gnu.org/software/classpath/license.html + * + * or as provided in the LICENSE.txt file that accompanied this code. + * 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.bytedeco.javacpp.indexer; + +/** + * TODO + * + * @author Matteo Di Giovinazzo + */ +public class CustomStridesIndex implements Index { + + protected final long[] strides; + + /** + * TODO + * + * @param strides The number of elements to skip to reach the next element in a given dimension. + * {@code strides[i] > strides[i + 1] && strides[strides.length - 1] == 1} preferred. + */ + protected CustomStridesIndex(long[] strides) { + this.strides = strides; + } + + public static Index customStrides(long[] strides) { + return new CustomStridesIndex(strides); + } + + @Override + public long index(long i) { + return i * strides[0]; + } + + @Override + public long index(long i, long j) { + return i * strides[0] + j * strides[1]; + } + + @Override + public long index(long i, long j, long k) { + return i * strides[0] + j * strides[1] + k * strides[2]; + } + + /** + * Computes the linear index as the dot product of indices and strides. + * + * @param indices of each dimension + * @return index to access array or buffer + */ + @Override + public long index(long... indices) { + long index = 0; + for (int i = 0; i < indices.length && i < strides.length; i++) { + index += indices[i] * strides[i]; + } + return index; + } +} diff --git a/src/main/java/org/bytedeco/javacpp/indexer/DefaultIndex.java b/src/main/java/org/bytedeco/javacpp/indexer/DefaultIndex.java new file mode 100644 index 000000000..953cb30fc --- /dev/null +++ b/src/main/java/org/bytedeco/javacpp/indexer/DefaultIndex.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2016-2019 Samuel Audet + * + * Licensed either under the Apache License, Version 2.0, or (at your option) + * under the terms of the GNU General Public License as published by + * the Free Software Foundation (subject to the "Classpath" exception), + * either version 2, or any later version (collectively, 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 + * http://www.gnu.org/licenses/ + * http://www.gnu.org/software/classpath/license.html + * + * or as provided in the LICENSE.txt file that accompanied this code. + * 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.bytedeco.javacpp.indexer; + +/** + * TODO + * + * @author Matteo Di Giovinazzo + */ +public class DefaultIndex extends CustomStridesIndex { + + protected DefaultIndex(long... sizes) { + super(strides(sizes)); + } + + public static Index defaultIndex(long[] sizes) { + return new DefaultIndex(sizes); + } + + /** + * Returns default (row-major contiguous) strides for the given sizes. + */ + public static long[] strides(long... sizes) { + long[] strides = new long[sizes.length]; + strides[sizes.length - 1] = 1; + for (int i = sizes.length - 2; i >= 0; i--) { + strides[i] = strides[i + 1] * sizes[i + 1]; + } + return strides; + } + +} diff --git a/src/main/java/org/bytedeco/javacpp/indexer/Index.java b/src/main/java/org/bytedeco/javacpp/indexer/Index.java new file mode 100644 index 000000000..c70405ea3 --- /dev/null +++ b/src/main/java/org/bytedeco/javacpp/indexer/Index.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2016-2019 Samuel Audet + * + * Licensed either under the Apache License, Version 2.0, or (at your option) + * under the terms of the GNU General Public License as published by + * the Free Software Foundation (subject to the "Classpath" exception), + * either version 2, or any later version (collectively, 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 + * http://www.gnu.org/licenses/ + * http://www.gnu.org/software/classpath/license.html + * + * or as provided in the LICENSE.txt file that accompanied this code. + * 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.bytedeco.javacpp.indexer; + +/** + * TODO + * + * @author Matteo Di Giovinazzo + */ +public interface Index { + + /** + * TODO + * + * @param i + * @return + */ + long index(long i); + + /** + * TODO + * + * @param i + * @param j + * @return + */ + long index(long i, long j); + + /** + * TODO + * + * @param i + * @param j + * @param k + * @return + */ + long index(long i, long j, long k); + + /** + * TODO + * + * @param indices + * @return + */ + long index(long... indices); + +} diff --git a/src/main/java/org/bytedeco/javacpp/indexer/Indexer.java b/src/main/java/org/bytedeco/javacpp/indexer/Indexer.java index c6a4bf3d3..41865cb39 100644 --- a/src/main/java/org/bytedeco/javacpp/indexer/Indexer.java +++ b/src/main/java/org/bytedeco/javacpp/indexer/Indexer.java @@ -22,9 +22,13 @@ package org.bytedeco.javacpp.indexer; -import java.nio.Buffer; import org.bytedeco.javacpp.Pointer; +import java.nio.Buffer; + +import static org.bytedeco.javacpp.indexer.CustomStridesIndex.customStrides; +import static org.bytedeco.javacpp.indexer.DefaultIndex.defaultIndex; + /** * Top-level class of all data indexers, providing easy-to-use and efficient * multidimensional access to primitive arrays, NIO buffers, and the raw memory interface. @@ -49,7 +53,7 @@ public abstract class Indexer implements AutoCloseable { release(); } - protected static final long[] ONE_STRIDE = { 1 }; + @Deprecated protected static final long[] ONE_STRIDE = { 1 }; /** * The number of elements in each dimension. @@ -60,23 +64,42 @@ public abstract class Indexer implements AutoCloseable { * The number of elements to skip to reach the next element in a given dimension. * {@code strides[i] > strides[i + 1] && strides[strides.length - 1] == 1} preferred. */ - protected long[] strides; + @Deprecated protected long[] strides; + /** + * TODO + */ + protected Index index; + + /** Constructor to set the {@link #sizes}. */ + protected Indexer(long[] sizes) { + this(sizes, defaultIndex(sizes)); + // XXX: access to strides for backward compatiility + assert index instanceof DefaultIndex; + this.strides = ((DefaultIndex) index).strides; + } - /** Constructor to set the {@link #sizes} and {@link #strides}. */ - protected Indexer(long[] sizes, long[] strides) { + /** Constructor to set the {@link #sizes} and {@link #index}. */ + protected Indexer(long[] sizes, Index index) { this.sizes = sizes; + this.index = index; + // XXX: what value should have strides in this case? + } + + /** Constructor to set the {@link #sizes} and {@link #strides}. */ + @Deprecated protected Indexer(long[] sizes, long[] strides) { + this(sizes, customStrides(strides)); this.strides = strides; } /** Returns {@link #sizes} */ public long[] sizes() { return sizes; } /** Returns {@link #strides} */ - public long[] strides() { return strides; } + @Deprecated public long[] strides() { return strides; } /** Returns {@code sizes[i]} */ public long size(int i) { return sizes[i]; } /** Returns {@code strides[i]} */ - public long stride(int i) { return strides[i]; } + @Deprecated public long stride(int i) { return strides[i]; } /** Returns {@code sizes.length > 0 && sizes.length < 4 ? sizes[0] : -1} */ @Deprecated public long rows() { return sizes.length > 0 && sizes.length < 4 ? sizes[0] : -1; } @@ -99,45 +122,11 @@ protected static final long checkIndex(long i, long size) { /** * Returns default (row-major contiguous) strides for the given sizes. */ + @Deprecated public static long[] strides(long... sizes) { - long[] strides = new long[sizes.length]; - strides[sizes.length - 1] = 1; - for (int i = sizes.length - 2; i >= 0; i--) { - strides[i] = strides[i + 1] * sizes[i + 1]; - } - return strides; + return DefaultIndex.strides(sizes); } - protected class Index { - public long index(long i) { - return i * strides[0]; - } - - public long index(long i, long j) { - return i * strides[0] + j * strides[1]; - } - - public long index(long i, long j, long k) { - return i * strides[0] + j * strides[1] + k * strides[2]; - } - - /** - * Computes the linear index as the dot product of indices and strides. - * - * @param indices of each dimension - * @return index to access array or buffer - */ - public long index(long... indices) { - long index = 0; - for (int i = 0; i < indices.length && i < strides.length; i++) { - index += indices[i] * strides[i]; - } - return index; - } - } - - protected Index index = new Index(); - /** Returns {@code index.index(i)}. */ public long index(long i) { return index.index(i); diff --git a/src/test/java/org/bytedeco/javacpp/IndexerTest.java b/src/test/java/org/bytedeco/javacpp/IndexerTest.java index 038701d47..ef2fa1754 100644 --- a/src/test/java/org/bytedeco/javacpp/IndexerTest.java +++ b/src/test/java/org/bytedeco/javacpp/IndexerTest.java @@ -42,6 +42,7 @@ import org.bytedeco.javacpp.indexer.UShortIndexer; import org.bytedeco.javacpp.indexer.UIntIndexer; import org.bytedeco.javacpp.indexer.ULongIndexer; +import org.bytedeco.javacpp.indexer.DefaultIndex; import org.bytedeco.javacpp.tools.Builder; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -74,7 +75,7 @@ public class IndexerTest { } static class TestIndexer extends Indexer { - TestIndexer(long[] sizes) { super(sizes, Indexer.strides(sizes)); } + TestIndexer(long[] sizes) { super(sizes, DefaultIndex.strides(sizes)); } public void release() { } public double getDouble(long... indices) { return 0; } public Indexer putDouble(long[] indices, double value) { return this; } @@ -83,7 +84,7 @@ public void release() { } @Test public void testIndexer() { System.out.println("Indexer"); long[] sizes = {640, 480, 3}; - long[] strides = Indexer.strides(sizes); + long[] strides = DefaultIndex.strides(sizes); System.out.println(Arrays.toString(strides)); assertEquals(1440, strides[0]); assertEquals( 3, strides[1]);