package org.apache.pig.backend.hadoop.executionengine.spark.converter; import org.apache.pig.backend.executionengine.ExecException; import org.apache.pig.backend.hadoop.executionengine.physicalLayer.POStatus; import org.apache.pig.backend.hadoop.executionengine.physicalLayer.Result; import org.apache.pig.data.Tuple; abstract class POOutputConsumerIterator implements java.util.Iterator<Tuple> { private final java.util.Iterator<Tuple> input; private Result result = null; private boolean returned = true; private boolean finished = false; POOutputConsumerIterator(java.util.Iterator<Tuple> input) { this.input = input; } abstract protected void attach(Tuple tuple); abstract protected Result getNextResult() throws ExecException; private void readNext() { try { if (result != null && !returned) { return; } // see PigGenericMapBase if (result == null) { if (!input.hasNext()) { finished = true; return; } Tuple v1 = input.next(); attach(v1); } result = getNextResult(); returned = false; switch (result.returnStatus) { case POStatus.STATUS_OK: { returned = false; break; } case POStatus.STATUS_NULL: { returned = true; // skip: see PigGenericMapBase readNext(); break; } case POStatus.STATUS_EOP: { finished = !input.hasNext(); if (!finished) { result = null; readNext(); } break; } case POStatus.STATUS_ERR: { throw new RuntimeException("Error while processing "+ result); } } } catch (ExecException e) { throw new RuntimeException(e); } } @Override public boolean hasNext() { readNext(); return !finished; } @Override public Tuple next() { readNext(); if (finished) { throw new RuntimeException("Passed the end. call hasNext() first"); } if (result == null || result.returnStatus != POStatus.STATUS_OK) { throw new RuntimeException("Unexpected response code in ForEach: " + result); } returned = true; return (Tuple) result.result; } @Override public void remove() { throw new UnsupportedOperationException(); } }