This is an automated email from the ASF dual-hosted git repository.
baunsgaard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/systemds.git
The following commit(s) were added to refs/heads/main by this push:
new 2ab0eb8fcf [SYSTEMDS-3491] CLA Specialized Column-Indexes
2ab0eb8fcf is described below
commit 2ab0eb8fcf5f5928d904e13518f0b99bbf7dc26c
Author: baunsgaard <[email protected]>
AuthorDate: Fri Jan 27 16:05:52 2023 +0100
[SYSTEMDS-3491] CLA Specialized Column-Indexes
This commit adds new specializations of the column indexes in
CLA. To avoid a major commit, this is the first commit in 3 parts
that will change the allocation of the columns from simple arrays to
these specializations. This part 1 is just the interface and classes
of the new arrays.
Closes #1774
---
.../compress/colgroup/indexes/ArrayIndex.java | 97 +++++++++
.../compress/colgroup/indexes/ColIndexFactory.java | 74 +++++++
.../compress/colgroup/indexes/IColIndex.java | 89 ++++++++
.../compress/colgroup/indexes/IIterate.java | 41 ++++
.../compress/colgroup/indexes/RangeIndex.java | 103 +++++++++
.../compress/colgroup/indexes/SingleIndex.java | 82 ++++++++
.../compress/colgroup/indexes/TwoIndex.java | 90 ++++++++
.../component/compress/indexes/IndexesTest.java | 234 +++++++++++++++++++++
.../compress/indexes/NegativeIndexTest.java | 51 +++++
9 files changed, 861 insertions(+)
diff --git
a/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/ArrayIndex.java
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/ArrayIndex.java
new file mode 100644
index 0000000000..d26307d352
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/ArrayIndex.java
@@ -0,0 +1,97 @@
+/*
+ * 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.sysds.runtime.compress.colgroup.indexes;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.sysds.utils.MemoryEstimates;
+
+public class ArrayIndex implements IColIndex {
+ private final int[] cols;
+
+ public ArrayIndex(int[] cols) {
+ this.cols = cols;
+ }
+
+ @Override
+ public int size() {
+ return cols.length;
+ }
+
+ @Override
+ public int get(int i) {
+ return cols[i];
+ }
+
+ @Override
+ public IColIndex shift(int i) {
+ int[] ret = new int[cols.length];
+ for(int j = 0; j < cols.length; j++)
+ ret[j] = cols[j] + i;
+ return new ArrayIndex(ret);
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeByte(ColIndexType.ARRAY.ordinal());
+ out.writeInt(cols.length);
+ for(int i = 0; i < cols.length; i++)
+ out.writeInt(cols[i]);
+ }
+
+ public static ArrayIndex read(DataInput in) throws IOException {
+ int size = in.readInt();
+ int[] cols = new int[size];
+ for(int i = 0; i < size; i++)
+ cols[i] = in.readInt();
+ return new ArrayIndex(cols);
+ }
+
+ @Override
+ public long getExactSizeOnDisk() {
+ return 1 + 4 + 4 * cols.length;
+ }
+
+ @Override
+ public long estimateInMemorySize() {
+ return 16 + (long) MemoryEstimates.intArrayCost(cols.length);
+ }
+
+ @Override
+ public IIterate iterator() {
+ return new ArrayIterator();
+ }
+
+ protected class ArrayIterator implements IIterate {
+ int id = 0;
+
+ @Override
+ public int next() {
+ return cols[id++];
+ }
+
+ @Override
+ public boolean hasNext() {
+ return id < cols.length;
+ }
+ }
+}
diff --git
a/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/ColIndexFactory.java
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/ColIndexFactory.java
new file mode 100644
index 0000000000..3926edc09c
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/ColIndexFactory.java
@@ -0,0 +1,74 @@
+/*
+ * 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.sysds.runtime.compress.colgroup.indexes;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+import org.apache.sysds.runtime.compress.DMLCompressionException;
+import
org.apache.sysds.runtime.compress.colgroup.indexes.IColIndex.ColIndexType;
+
+public interface ColIndexFactory {
+
+ public static IColIndex read(DataInput in) throws IOException {
+ final ColIndexType t = ColIndexType.values()[in.readByte()];
+ switch(t) {
+ case SINGLE:
+ return new SingleIndex(in.readInt());
+ case TWO:
+ return new TwoIndex(in.readInt(), in.readInt());
+ case ARRAY:
+ return ArrayIndex.read(in);
+ case RANGE:
+ return RangeIndex.read(in);
+ default:
+ throw new DMLCompressionException("Failed
reading column index of type: " + t);
+ }
+ }
+
+ public static IColIndex create(int[] indexes) {
+ if(indexes.length == 1)
+ return new SingleIndex(indexes[0]);
+ else if(indexes.length == 2)
+ return new TwoIndex(indexes[0], indexes[1]);
+ else if(RangeIndex.isValidRange(indexes))
+ return new RangeIndex(indexes[0], indexes[0] +
indexes.length);
+ else
+ return new ArrayIndex(indexes);
+ }
+
+ public static IColIndex create(int l, int u) {
+ if(u - 1 == l)
+ return new SingleIndex(l);
+ else if(u - 2 == l)
+ return new TwoIndex(l, l + 1);
+ else
+ return new RangeIndex(l, u);
+ }
+
+ public static IColIndex create(int nCol) {
+ if(nCol == 1)
+ return new SingleIndex(0);
+ else if(nCol == 2)
+ return new TwoIndex(0, 1);
+ else
+ return new RangeIndex(nCol);
+ }
+}
diff --git
a/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/IColIndex.java
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/IColIndex.java
new file mode 100644
index 0000000000..e2d7ff8985
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/IColIndex.java
@@ -0,0 +1,89 @@
+/*
+ * 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.sysds.runtime.compress.colgroup.indexes;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Class to contain column indexes for the compression column groups.
+ */
+public interface IColIndex {
+
+ public static enum ColIndexType {
+ SINGLE, TWO, ARRAY, RANGE, UNKNOWN;
+ }
+
+ /**
+ * Get the size of the index aka, how many columns is contained
+ *
+ * @return The size of the array
+ */
+ public int size();
+
+ /**
+ * Get the index at a specific location, Note that many of the
underlying implementations does not throw exceptions
+ * on indexes that are completely wrong, so all implementations that
use this index should always be well behaved.
+ *
+ * @param i The index to get
+ * @return the column index at the index.
+ */
+ public int get(int i);
+
+ /**
+ * Return a new column index where the values are shifted by the
specified amount.
+ *
+ * It is returning a new instance of the index.
+ *
+ * @param i The amount to shift
+ * @return the new instance of an index.
+ */
+ public IColIndex shift(int i);
+
+ /**
+ * Write out the IO representation of this column index
+ *
+ * @param out The Output to write into
+ * @throws IOException IO exceptions in case of for instance not enough
disk space
+ */
+ public void write(DataOutput out) throws IOException;
+
+ /**
+ * Get the exact size on disk to enable preallocation of the disk
output buffer sizes
+ *
+ * @return The exact disk representation size
+ */
+ public long getExactSizeOnDisk();
+
+ /**
+ * Get the in memory size of this object.
+ *
+ * @return The memory size of this object
+ */
+ public long estimateInMemorySize();
+
+ /**
+ * A Iterator of the indexes see the iterator interface for details.
+ *
+ * @return A iterator for the indexes contained.
+ */
+ public IIterate iterator();
+
+}
diff --git
a/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/IIterate.java
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/IIterate.java
new file mode 100644
index 0000000000..fae615c9ec
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/IIterate.java
@@ -0,0 +1,41 @@
+/*
+ * 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.sysds.runtime.compress.colgroup.indexes;
+
+/**
+ * Class to iterate through the columns of a IColIndex.
+ *
+ * When initialized it should be at index -1 and then at the call to next you
get the first value
+ */
+public interface IIterate {
+ /**
+ * Get next index
+ *
+ * @return the index.
+ */
+ public int next();
+
+ /**
+ * Get if the index has a next index.
+ *
+ * @return the next index.
+ */
+ public boolean hasNext();
+}
diff --git
a/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/RangeIndex.java
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/RangeIndex.java
new file mode 100644
index 0000000000..87e74185a1
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/RangeIndex.java
@@ -0,0 +1,103 @@
+/*
+ * 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.sysds.runtime.compress.colgroup.indexes;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class RangeIndex implements IColIndex {
+ private final int l;
+ private final int u; // not inclusive
+
+ public RangeIndex(int nCol) {
+ l = 0;
+ u = nCol;
+ }
+
+ public RangeIndex(int l, int u) {
+ this.l = l;
+ this.u = u;
+ }
+
+ @Override
+ public int size() {
+ return u - l;
+ }
+
+ @Override
+ public int get(int i) {
+ return l + i;
+ }
+
+ @Override
+ public IColIndex shift(int i) {
+ return new RangeIndex(l + i, u + i);
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.writeByte(ColIndexType.RANGE.ordinal());
+ out.writeInt(l);
+ out.writeInt(u);
+ }
+
+ public static RangeIndex read(DataInput in) throws IOException {
+ int l = in.readInt();
+ int u = in.readInt();
+ return new RangeIndex(l, u);
+ }
+
+ @Override
+ public long getExactSizeOnDisk() {
+ return 1 + 4 + 4;
+ }
+
+ @Override
+ public long estimateInMemorySize() {
+ return 16 + 8;
+ }
+
+ @Override
+ public IIterate iterator() {
+ return new RangeIterator();
+ }
+
+ protected static boolean isValidRange(int[] indexes) {
+ int len = indexes.length;
+ int first = indexes[0];
+ int last = indexes[indexes.length - 1];
+ return last - first + 1 == len;
+ }
+
+ protected class RangeIterator implements IIterate {
+ int cl = l;
+
+ @Override
+ public int next() {
+ return cl++;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return cl < u;
+ }
+ }
+}
diff --git
a/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/SingleIndex.java
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/SingleIndex.java
new file mode 100644
index 0000000000..939fe3a927
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/SingleIndex.java
@@ -0,0 +1,82 @@
+/*
+ * 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.sysds.runtime.compress.colgroup.indexes;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class SingleIndex implements IColIndex {
+ private final int idx;
+
+ public SingleIndex(int idx) {
+ this.idx = idx;
+ }
+
+ @Override
+ public int size() {
+ return 1;
+ }
+
+ @Override
+ public int get(int i) {
+ return idx;
+ }
+
+ @Override
+ public SingleIndex shift(int i) {
+ return new SingleIndex(i + idx);
+ }
+
+ @Override
+ public IIterate iterator() {
+ return new SingleIterator();
+ }
+
+ public void write(DataOutput out) throws IOException {
+ out.writeByte(ColIndexType.SINGLE.ordinal());
+ out.writeInt(idx);
+ }
+
+ @Override
+ public long getExactSizeOnDisk() {
+ return 1 + 4;
+ }
+
+ @Override
+ public long estimateInMemorySize() {
+ return 16 + 4 + 4; // object, int, and padding
+ }
+
+ protected class SingleIterator implements IIterate {
+ boolean taken = false;
+
+ @Override
+ public int next() {
+ taken = true;
+ return idx;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !taken;
+ }
+ }
+
+}
diff --git
a/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/TwoIndex.java
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/TwoIndex.java
new file mode 100644
index 0000000000..7947d853fa
--- /dev/null
+++
b/src/main/java/org/apache/sysds/runtime/compress/colgroup/indexes/TwoIndex.java
@@ -0,0 +1,90 @@
+/*
+ * 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.sysds.runtime.compress.colgroup.indexes;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class TwoIndex implements IColIndex {
+ private final int id1;
+ private final int id2;
+
+ public TwoIndex(int id1, int id2) {
+ this.id1 = id1;
+ this.id2 = id2;
+ }
+
+ @Override
+ public int size() {
+ return 2;
+ }
+
+ @Override
+ public int get(int i) {
+ if(i == 0)
+ return id1;
+ else
+ return id2;
+ }
+
+ @Override
+ public TwoIndex shift(int i) {
+ return new TwoIndex(id1 + i, id2 + i);
+ }
+
+ @Override
+ public IIterate iterator() {
+ return new TwoIterator();
+ }
+
+ public void write(DataOutput out) throws IOException {
+ out.writeByte(ColIndexType.TWO.ordinal());
+ out.writeInt(id1);
+ out.writeInt(id2);
+ }
+
+ @Override
+ public long getExactSizeOnDisk() {
+ return 1 + 4 + 4;
+ }
+
+ @Override
+ public long estimateInMemorySize() {
+ return 16 + 8; // object, 2x int
+ }
+
+ protected class TwoIterator implements IIterate {
+ int id = 0;
+
+ @Override
+ public int next() {
+ if(id++ == 0)
+ return id1;
+ else
+ return id2;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return id < 2;
+ }
+ }
+
+}
diff --git
a/src/test/java/org/apache/sysds/test/component/compress/indexes/IndexesTest.java
b/src/test/java/org/apache/sysds/test/component/compress/indexes/IndexesTest.java
new file mode 100644
index 0000000000..043b51c5d6
--- /dev/null
+++
b/src/test/java/org/apache/sysds/test/component/compress/indexes/IndexesTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.sysds.test.component.compress.indexes;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.sysds.runtime.compress.colgroup.indexes.ColIndexFactory;
+import org.apache.sysds.runtime.compress.colgroup.indexes.IColIndex;
+import org.apache.sysds.runtime.compress.colgroup.indexes.IIterate;
+import org.apache.sysds.runtime.compress.colgroup.indexes.SingleIndex;
+import org.apache.sysds.runtime.compress.colgroup.indexes.TwoIndex;
+import org.apache.sysds.utils.MemoryEstimates;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(value = Parameterized.class)
+public class IndexesTest {
+
+ private final int[] expected;
+ private final IColIndex actual;
+
+ @Parameters
+ public static Collection<Object[]> data() {
+ List<Object[]> tests = new ArrayList<>();
+
+ try {
+ // single
+ tests.add(new Object[] {new int[] {0}, new
SingleIndex(0)});
+ tests.add(new Object[] {new int[] {334},
ColIndexFactory.create(334, 335)});
+ tests.add(new Object[] {new int[] {0},
ColIndexFactory.create(1)});
+ tests.add(new Object[] {new int[] {0},
ColIndexFactory.create(new int[] {0})});
+ tests.add(new Object[] {new int[] {320},
ColIndexFactory.create(new int[] {320})});
+
+ // two
+ tests.add(new Object[] {new int[] {0, 1}, new
TwoIndex(0, 1)});
+ tests.add(new Object[] {new int[] {3214, 44444}, new
TwoIndex(3214, 44444)});
+ tests.add(new Object[] {new int[] {3214, 44444},
ColIndexFactory.create(new int[] {3214, 44444})});
+ tests.add(new Object[] {new int[] {3214, 3215},
ColIndexFactory.create(3214, 3216)});
+ tests.add(new Object[] {new int[] {0, 1},
ColIndexFactory.create(2)});
+
+ // array
+ tests.add(create(32, 14));
+ tests.add(create(40, 21));
+ tests.add(new Object[] {//
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, //
+ ColIndexFactory.create(0, 10)});
+
+ tests.add(new Object[] {//
+ new int[] {0, 1, 2, 3}, //
+ ColIndexFactory.create(0, 4)});
+
+ tests.add(new Object[] {//
+ new int[] {0, 1, 2, 3}, //
+ ColIndexFactory.create(4)});
+
+ tests.add(new Object[] {//
+ new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, //
+ ColIndexFactory.create(10)});
+
+ tests.add(new Object[] {//
+ new int[] {4, 5, 6, 7, 8, 9}, //
+ ColIndexFactory.create(4, 10)});
+
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ fail("failed constructing tests");
+ }
+
+ return tests;
+ }
+
+ public IndexesTest(int[] expected, IColIndex actual) {
+ this.expected = expected;
+ this.actual = actual;
+ }
+
+ @Test
+ public void testGet() {
+ for(int i = 0; i < expected.length; i++) {
+ assertEquals(expected[i], actual.get(i));
+ }
+ }
+
+ @Test
+ public void testSerialize() {
+ try {
+ // Serialize out
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream fos = new DataOutputStream(bos);
+ actual.write(fos);
+
+ // Serialize in
+ ByteArrayInputStream bis = new
ByteArrayInputStream(bos.toByteArray());
+ DataInputStream fis = new DataInputStream(bis);
+
+ IColIndex n = ColIndexFactory.read(fis);
+
+ compare(actual, n);
+ }
+ catch(IOException e) {
+ throw new RuntimeException("Error in io", e);
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ @Test
+ public void testSerializeSize() {
+ try {
+ // Serialize out
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream fos = new DataOutputStream(bos);
+ actual.write(fos);
+
+ long actualSize = bos.size();
+ long expectedSize = actual.getExactSizeOnDisk();
+
+ assertEquals(expectedSize, actualSize);
+ }
+ catch(IOException e) {
+ throw new RuntimeException("Error in io", e);
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+ @Test
+ public void testSize() {
+ assertEquals(expected.length, actual.size());
+ }
+
+
+ @Test
+ public void iterator() {
+ compare(expected, actual.iterator());
+ }
+
+ @Test
+ public void factoryCreate() {
+ compare(expected, ColIndexFactory.create(expected));
+ }
+
+ @Test
+ public void shift() {
+ shift(5);
+ }
+
+ @Test
+ public void shift2() {
+ shift(1342);
+ }
+
+ @Test
+ public void estimateInMemorySizeIsNotToBig() {
+ assertTrue(MemoryEstimates.intArrayCost(expected.length) >=
actual.estimateInMemorySize() - 16);
+ }
+
+ private void shift(int i) {
+ compare(expected, actual.shift(i), i);
+ }
+
+ private static void compare(int[] expected, IColIndex actual) {
+ assertEquals(expected.length, actual.size());
+ for(int i = 0; i < expected.length; i++)
+ assertEquals(expected[i], actual.get(i));
+ }
+
+ private static void compare(int[] expected, IColIndex actual, int off) {
+ assertEquals(expected.length, actual.size());
+ for(int i = 0; i < expected.length; i++)
+ assertEquals(expected[i] + off, actual.get(i));
+ }
+
+ private static void compare(IColIndex expected, IColIndex actual) {
+ assertEquals(expected.size(), actual.size());
+ for(int i = 0; i < expected.size(); i++)
+ assertEquals(expected.get(i), actual.get(i));
+ }
+
+ private static void compare(int[] expected, IIterate actual) {
+ for(int i = 0; i < expected.length; i++) {
+ assertTrue(actual.hasNext());
+ assertEquals(expected[i], actual.next());
+ }
+ assertFalse(actual.hasNext());
+ }
+
+ private static Object[] create(int size, int seed) {
+ int[] cols = new int[size];
+ Random r = new Random(seed);
+ cols[0] = r.nextInt(1000) + 1;
+ for(int i = 1; i < size; i++) {
+ cols[i] = cols[i - 1] + r.nextInt(1000) + 1;
+ }
+ return new Object[] {cols, ColIndexFactory.create(cols)};
+ }
+}
diff --git
a/src/test/java/org/apache/sysds/test/component/compress/indexes/NegativeIndexTest.java
b/src/test/java/org/apache/sysds/test/component/compress/indexes/NegativeIndexTest.java
new file mode 100644
index 0000000000..adda18c57b
--- /dev/null
+++
b/src/test/java/org/apache/sysds/test/component/compress/indexes/NegativeIndexTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.sysds.test.component.compress.indexes;
+
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.sysds.runtime.compress.DMLCompressionException;
+import org.apache.sysds.runtime.compress.colgroup.indexes.ColIndexFactory;
+import
org.apache.sysds.runtime.compress.colgroup.indexes.IColIndex.ColIndexType;
+import org.junit.Test;
+
+public class NegativeIndexTest {
+ @Test(expected = DMLCompressionException.class)
+ public void notValidRead() {
+ try {
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream fos = new DataOutputStream(bos);
+ fos.writeByte(ColIndexType.UNKNOWN.ordinal());
+ ByteArrayInputStream bis = new
ByteArrayInputStream(bos.toByteArray());
+ DataInputStream fis = new DataInputStream(bis);
+ ColIndexFactory.read(fis);
+ }
+ catch(IOException e) {
+ fail("Wrong type of exception");
+ }
+ }
+}