blob: 711236cb29af46e7b003a52c68a8d911b63398d8 [file] [log] [blame]
/*
* 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 java.util.Arrays;
import java.util.stream.IntStream;
import org.apache.sysds.utils.MemoryEstimates;
public class ArrayIndex extends AColIndex {
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 estimateInMemorySizeStatic(cols.length);
}
public static long estimateInMemorySizeStatic(int nCol) {
return 16 + (long) MemoryEstimates.intArrayCost(nCol);
}
@Override
public IIterate iterator() {
return new ArrayIterator();
}
@Override
public int findIndex(int i) {
return Arrays.binarySearch(cols, i);
}
@Override
public boolean isContiguous() {
return false;
}
@Override
public SliceResult slice(int l, int u) {
if(l == 0 && u > cols[cols.length - 1])
return new SliceResult(0, cols.length, this);
int s = Arrays.binarySearch(cols, l);
int e = Arrays.binarySearch(cols, u);
s = s < 0 ? Math.abs(s + 1) : s;
e = e < 0 ? Math.abs(e + 1) : e;
if(s == e)
return new SliceResult(0, 0, null);
int[] retArr = new int[e - s];
if(l == 0)
retArr = Arrays.copyOfRange(cols, s, e);
else
for(int i = s, j = 0; i < e; i++, j++)
retArr[j] = cols[i] - l;
SliceResult ret = new SliceResult(s, e, ColIndexFactory.create(retArr));
return ret;
}
@Override
public boolean equals(IColIndex other) {
if(other.size() == size()) {
if(other instanceof ArrayIndex) {
ArrayIndex ot = (ArrayIndex) other;
int[] otV = ot.cols;
return Arrays.equals(cols, otV);
}
else if(other instanceof RangeIndex)
return other.get(0) == cols[0] && other.get(size() - 1) == cols[size() - 1];
else { // generic
for(int i = 0; i < size(); i++)
if(other.get(i) != cols[i])
return false;
return true;
}
}
return false;
}
@Override
public IColIndex combine(IColIndex other) {
final int sr = other.size();
final int sl = size();
final int[] ret = new int[sr + sl];
int pl = 0;
int pr = 0;
int i = 0;
while(pl < sl && pr < sr) {
final int vl = get(pl);
final int vr = other.get(pr);
if(vl < vr) {
ret[i++] = vl;
pl++;
}
else {
ret[i++] = vr;
pr++;
}
}
while(pl < sl)
ret[i++] = get(pl++);
while(pr < sr)
ret[i++] = other.get(pr++);
return ColIndexFactory.create(ret);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.getClass().getSimpleName());
sb.append(Arrays.toString(cols));
return sb.toString();
}
@Override
public int[] getReorderingIndex() {
int[] sortedIndices = IntStream.range(0, cols.length).boxed()//
.sorted((i, j) -> Integer.valueOf(cols[i]).compareTo(cols[j]))//
.mapToInt(ele -> ele).toArray();
return sortedIndices;
}
@Override
public boolean isSorted() {
for(int i = 1; i < cols.length; i++)
if(cols[i - 1] > cols[i])
return false;
return true;
}
@Override
public IColIndex sort() {
int[] ret = new int[cols.length];
System.arraycopy(cols, 0, ret, 0, cols.length);
Arrays.sort(ret);
return ColIndexFactory.create(ret);
}
@Override
public boolean contains(int i) {
int id = Arrays.binarySearch(cols, 0, cols.length, i);
return id >= 0;
}
protected class ArrayIterator implements IIterate {
int id = 0;
@Override
public int next() {
return cols[id++];
}
@Override
public boolean hasNext() {
return id < cols.length;
}
@Override
public int v() {
return cols[id];
}
@Override
public int i() {
return id;
}
}
}