package water.udf; import water.fvec.Chunk; import water.fvec.RawChunk; import water.fvec.Vec; import water.util.fp.Function; import static water.util.Java7.*; /** * This column depends on another column */ public class FunColumn<X, Y> extends FunColumnBase<Y> { private final Function<X, Y> f; private final Column<X> xs; @Override public int rowLayout() { return xs.rowLayout(); } /** * deserialization :( */ public FunColumn() { f = null; xs = null; } public FunColumn(Function<X, Y> f, Column<X> xs) { super(xs); this.f = f; this.xs = xs; } @Override public TypedChunk<Y> chunkAt(int i) { return new FunChunk(xs.chunkAt(i)); } public Y get(long idx) { return isNA(idx) ? null : f.apply(xs.apply(idx)); } @Override public boolean isNA(long idx) { return xs.isNA(idx); } /** * Pretends to be a chunk of a column, for distributed calculations. * Has type, and is not materialized */ public class FunChunk extends DependentChunk<Y> { private final TypedChunk<X> cx; public FunChunk(TypedChunk<X> cx) { super(cx); this.cx = cx; } @Override public Vec vec() { return FunColumn.this.vec(); } @Override public int length() { return cx.length(); } private RawChunk myChunk = new RawChunk(this); @Override public Chunk rawChunk() { return myChunk; } @Override public boolean isNA(int i) { return cx.isNA(i); } @Override public Y get(int i) { return f.apply(cx.get(i)); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o instanceof FunColumn) { FunColumn other = (FunColumn) o; return Objects.equals(f, other.f) && xs.equals(other.xs); } return false; } @Override public int hashCode() { return 61 * xs.hashCode() + Objects.hashCode(f); } @Override public String toString() { return "FunColumn(" + f.getClass().getSimpleName() + "," + xs + ")"; } }