}
// Limit can be duplicated, and the new instance pushed in front of an operator for the following operators
// (that is, if you have X->limit, you can transform that to limit->X->limit):
else if (predecessor instanceof LOCross || predecessor instanceof LOUnion)
{
LOLimit newLimit = null;
List<LogicalOperator> nodesToProcess = new ArrayList<LogicalOperator>();
for (LogicalOperator prepredecessor:mPlan.getPredecessors(predecessor))
nodesToProcess.add(prepredecessor);
for (LogicalOperator prepredecessor:nodesToProcess)
{
try {
newLimit = limit.duplicate();
insertBetween(prepredecessor, newLimit, predecessor, null);
} catch (Exception e) {
int errCode = 2011;
String msg = "Can not insert LOLimit clone";
throw new OptimizerException(msg, errCode, PigException.BUG, e);
}
// we can move the new LOLimit even further, recursively optimize LOLimit
processNode(newLimit);
}
}
// Limit can be merged into LOSort, result a "limited sort"
else if (predecessor instanceof LOSort)
{
if(mode == ExecType.LOCAL) {
//We don't need this optimisation to happen in the local mode.
//so we do nothing here.
} else {
LOSort sort = (LOSort)predecessor;
if (sort.getLimit()==-1)
sort.setLimit(limit.getLimit());
else
sort.setLimit(sort.getLimit()<limit.getLimit()?sort.getLimit():limit.getLimit());
try {
mPlan.removeAndReconnect(limit);
} catch (Exception e) {
int errCode = 2012;
String msg = "Can not remove LOLimit after LOSort";
throw new OptimizerException(msg, errCode, PigException.BUG, e);
}
}
}
// Limit is merged into another LOLimit
else if (predecessor instanceof LOLimit)
{
LOLimit beforeLimit = (LOLimit)predecessor;
beforeLimit.setLimit(beforeLimit.getLimit()<limit.getLimit()?beforeLimit.getLimit():limit.getLimit());
try {
mPlan.removeAndReconnect(limit);
} catch (Exception e) {
int errCode = 2012;
String msg = "Can not remove LOLimit after LOLimit";