}
while (res.returnStatus == POStatus.STATUS_EOP) {
boolean hasData = false;
Object cur = null;
PigNullableWritable min = null;
int minIndex = -1;
try {
for (int i = 0; i < numInputs; i++) {
if (!finished[i]) {
hasData = true;
cur = readers.get(i).getCurrentKey();
if (min == null || comparator.compare(min, cur) > 0) {
//Not a deep clone. Writable is referenced.
min = ((PigNullableWritable)cur).clone();
minIndex = i;
}
}
}
} catch (Exception e) {
throw new ExecException(e);
}
if (!hasData) {
// For certain operators (such as STREAM), we could still have some work
// to do even after seeing the last input. These operators set a flag that
// says all input has been sent and to run the pipeline one more time.
if (Boolean.valueOf(conf.get(JobControlCompiler.END_OF_INP_IN_MAP, "false"))) {
this.parentPlan.endOfAllInput = true;
}
return new Result(POStatus.STATUS_EOP, null);
}
key = pkgr.getKey(min);
keyWritable = min;
try {
DataBag[] bags = new DataBag[numInputs];
if (isAccumulative()) {
buffer.setCurrentKey(min);
buffer.setCurrentKeyIndex(minIndex);
for (int i = 0; i < numInputs; i++) {
bags[i] = new AccumulativeBag(buffer, i);
}
} else {
for (int i = 0; i < numInputs; i++) {
DataBag bag = null;
if (!finished[i]) {
cur = readers.get(i).getCurrentKey();
// We need to loop in case of Grouping Comparators
while (comparator.compare(min, cur) == 0
&& (!min.isNull() || (min.isNull() && i == minIndex))) {
Iterable<Object> vals = readers.get(i).getCurrentValues();
bag = bags[i] == null ? new InternalCachedBag(numInputs) : bags[i];
for (Object val : vals) {
NullableTuple nTup = (NullableTuple) val;
int index = nTup.getIndex();