package water.udf; import water.fvec.Chunk; import water.fvec.RawChunk; import water.fvec.Vec; import water.util.fp.Function3; import static water.util.Java7.*; /** * This column depends on three other columns */ public class Fun3Column<X, Y, Z, T> extends FunColumnBase<T> { private final Function3<X, Y, Z, T> f; private final Column<X> xs; private final Column<Y> ys; private final Column<Z> zs; @Override public int rowLayout() { return xs.rowLayout(); } /** * deserialization :( */ public Fun3Column() { f = null; xs = null; ys = null; zs = null; } public Fun3Column(Function3<X, Y, Z, T> f, Column<X> xs, Column<Y> ys, Column<Z> zs) { super(xs); this.f = f; this.xs = xs; this.ys = ys; this.zs = zs; assert xs.isCompatibleWith(ys) : "Columns 1 and 2 must be compatible: " + xs + ", " + ys; assert xs.isCompatibleWith(zs) : "Columns 1 and 3 must be compatible: " + xs + ", " + zs; } @Override public T get(long idx) { return isNA(idx) ? null : f.apply(xs.apply(idx), ys.apply(idx), zs.apply(idx)); } @Override public TypedChunk<T> chunkAt(int i) { return new FunChunk(xs.chunkAt(i), ys.chunkAt(i), zs.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<T> { private final TypedChunk<X> cx; private final TypedChunk<Y> cy; private final TypedChunk<Z> cz; public FunChunk(TypedChunk<X> cx, TypedChunk<Y> cy, TypedChunk<Z> cz) { super(cx); this.cx = cx; this.cy = cy; this.cz = cz; } private RawChunk myChunk = new RawChunk(this); @Override public Chunk rawChunk() { return myChunk; } @Override public Vec vec() { return Fun3Column.this.vec(); } @Override public boolean isNA(int i) { return cx.isNA(i) || cy.isNA(i) || cz.isNA(i); } @Override public T get(int i) { return f.apply(cx.get(i), cy.get(i), cz.get(i)); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o instanceof Fun3Column) { Fun3Column other = (Fun3Column) 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 "Fun3Column(" + f.getClass().getSimpleName() + "," + xs + "," + ys+ "," + zs + ")"; } }