package water.udf;
import water.H2O;
import water.util.fp.Unfoldable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static water.util.Java7.*;
/**
* This column depends a plurality of columns
*/
public class UnfoldingColumn<X, Y> extends FunColumnBase<List<Y>> {
private final Unfoldable<X, Y> f;
private final Column<X> column;
private int requiredSize;
@Override public long size() { return column.size(); }
@Override public int rowLayout() { return column.rowLayout(); }
/**
* deserialization :(
*/
public UnfoldingColumn() {
f = null;
column = null;
}
public UnfoldingColumn(Unfoldable<X, Y> f, Column<X> column) {
super(column);
this.f = f;
this.column = column;
this.requiredSize = 0;
}
public UnfoldingColumn(Unfoldable<X, Y> f, Column<X> column, int requiredSize) {
super(column);
this.f = f;
this.column = column;
this.requiredSize = requiredSize;
}
public List<Y> get(long idx) {
List<Y> raw = isNA(idx) ? Collections.<Y>emptyList() : f.apply(column.apply(idx));
if (requiredSize == 0 || raw.size() == requiredSize) return raw;
else {
List<Y> result = raw.subList(0, Math.min(raw.size(), requiredSize));
if (result.size() < requiredSize) {
List<Y> fullResult = new ArrayList<>(requiredSize);
fullResult.addAll(result);
for (int i = result.size(); i < requiredSize; i++) {
fullResult.add(null);
}
return fullResult;
}
return result;
}
}
@Override public List<Y> apply(long idx) { return get(idx); }
@Override public List<Y> apply(Long idx) { return get(idx); }
@Override
public TypedChunk<List<Y>> chunkAt(int i) {
throw H2O.unimpl("Will have to think how to implement multi-string chunks...");
}
@Override public boolean isNA(long idx) {
return column.isNA(idx);
}
public static String join(String delimiter, Iterable<?> xs) {
StringBuilder sb = new StringBuilder();
for (Object x : xs) {
if (sb.length() > 0) sb.append(delimiter);
sb.append(x);
}
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o instanceof UnfoldingColumn) {
UnfoldingColumn<?, ?> that = (UnfoldingColumn<?, ?>) o;
return (requiredSize == that.requiredSize) &&
Objects.equals(f, that.f) &&
column.equals(that.column);
} else return false;
}
@Override
public int hashCode() {
int result = 61 * column.hashCode() + Objects.hashCode(f);
return 19 * result + requiredSize;
}
}