package water.rapids.ast.prims.search; import water.Futures; import water.MRTask; import water.fvec.*; import water.rapids.Env; import water.rapids.vals.ValFrame; import water.rapids.ast.AstPrimitive; import water.rapids.ast.AstRoot; /** * Indices of which entries are not equal to 0 */ public class AstWhich extends AstPrimitive { @Override public String[] args() { return new String[]{"ary"}; } @Override public int nargs() { return 1 + 1; } // (which col) @Override public String str() { return "which"; } @Override public ValFrame apply(Env env, Env.StackHelp stk, AstRoot asts[]) { Frame f = stk.track(asts[1].exec(env)).getFrame(); // The 1-row version if (f.numRows() == 1 && f.numCols() > 1) { AppendableVec v = new AppendableVec(Vec.VectorGroup.VG_LEN1.addVec(), Vec.T_NUM); NewChunk chunk = new NewChunk(v, 0); for (int i = 0; i < f.numCols(); i++) if (f.vecs()[i].at8(0) != 0) chunk.addNum(i); Futures fs = chunk.close(0, new Futures()); Vec vec = v.layout_and_close(fs); fs.blockForPending(); return new ValFrame(new Frame(vec)); } // The 1-column version Vec vec = f.anyVec(); if (f.numCols() > 1 || !vec.isInt()) throw new IllegalArgumentException("which requires a single integer column"); Frame f2 = new MRTask() { @Override public void map(Chunk c, NewChunk nc) { long start = c.start(); for (int i = 0; i < c._len; ++i) if (c.at8(i) != 0) nc.addNum(start + i); } }.doAll(new byte[]{Vec.T_NUM}, vec).outputFrame(); return new ValFrame(f2); } }