package water.udf; import water.fvec.Chunk; import water.fvec.RawChunk; import water.fvec.Vec; import water.util.fp.Function2; import static water.util.Java7.*; /** * This column depends on two other columns */ public class Fun2Column<X, Y, Z> extends FunColumnBase<Z> { private final Function2<X, Y, Z> f; private final Column<X> xs; private final Column<Y> ys; @Override public int rowLayout() { return xs.rowLayout(); } /** * deserialization :( */ public Fun2Column() { f = null; xs = null; ys = null; } public Fun2Column(Function2<X, Y, Z> f, Column<X> xs, Column<Y> ys) { super(xs); this.f = f; this.xs = xs; this.ys = ys; assert xs.isCompatibleWith(ys) : "Columns must be compatible: " + xs + ", " + ys; } @Override public Z get(long idx) { return isNA(idx) ? null : f.apply(xs.apply(idx), ys.apply(idx)); } @Override public TypedChunk<Z> chunkAt(int i) { return new FunChunk(xs.chunkAt(i), ys.chunkAt(i)); } @Override public boolean isNA(long idx) { return xs.isNA(idx) || ys.isNA(idx); } /** * Pretends to be a chunk of a column, for distributed calculations. * Has type, and is not materialized */ public class FunChunk extends DependentChunk<Z> { private final TypedChunk<X> cx; private final TypedChunk<Y> cy; private RawChunk myChunk = new RawChunk(this); @Override public Chunk rawChunk() { return myChunk; } @Override public Vec vec() { return Fun2Column.this.vec(); } public FunChunk(TypedChunk<X> cx, TypedChunk<Y> cy) { super(cx); this.cx = cx; this.cy = cy; } @Override public boolean isNA(int i) { return cx.isNA(i) || cy.isNA(i); } @Override public Z get(int i) { return f.apply(cx.get(i), cy.get(i)); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o instanceof Fun2Column) { Fun2Column other = (Fun2Column) 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 "Fun2Column(" + f.getClass().getSimpleName() + "," + xs + "," + ys + ")"; } }