/***********************************************************************************************************************
*
* Copyright (C) 2010 by the Stratosphere project (http://stratosphere.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
**********************************************************************************************************************/
package eu.stratosphere.pact.compiler.costs;
import java.util.List;
import eu.stratosphere.pact.compiler.CompilerException;
import eu.stratosphere.pact.compiler.Costs;
import eu.stratosphere.pact.compiler.plan.OptimizerNode;
import eu.stratosphere.pact.compiler.plan.PactConnection;
import eu.stratosphere.pact.runtime.resettable.BlockResettableMutableObjectIterator;
/**
* @author Stephan Ewen (stephan.ewen@tu-berlin.de)
*/
public abstract class CostEstimator {
public abstract void getRangePartitionCost(PactConnection conn, Costs costs);
public abstract void getHashPartitioningCost(PactConnection conn, Costs costs);
public abstract void getBroadcastCost(PactConnection conn, Costs costs);
// ------------------------------------------------------------------------
public abstract void getLocalSortCost(OptimizerNode node, PactConnection input, Costs costs);
public abstract void getLocalDoubleSortMergeCost(OptimizerNode node, PactConnection input1, PactConnection input2,
Costs costs);
public abstract void getLocalSingleSortMergeCost(OptimizerNode node, PactConnection input1, PactConnection input2,
Costs costs);
public abstract void getLocalMergeCost(OptimizerNode node, PactConnection input1, PactConnection input2,
Costs costs);
public abstract void getLocalSortSelfNestedLoopCost(OptimizerNode node, PactConnection input, int bufferSize, Costs costs);
public abstract void getLocalSelfNestedLoopCost(OptimizerNode node, PactConnection input, int bufferSize, Costs costs);
public abstract void getHybridHashCosts(OptimizerNode node, PactConnection buildSideInput,
PactConnection probeSideInput, Costs costs);
public abstract void getMainMemHashCosts(OptimizerNode node, PactConnection buildSideInput,
PactConnection probeSideInput, Costs costs);
public abstract void getStreamedNestedLoopsCosts(OptimizerNode node, PactConnection outerSide,
PactConnection innerSide, int bufferSize, Costs costs);
public abstract void getBlockNestedLoopsCosts(OptimizerNode node, PactConnection outerSide, PactConnection innerSide,
int blockSize, Costs costs);
// ------------------------------------------------------------------------
/**
* This method computes the costs for an operator. It requires that all inputs are set and have a proper
* <tt>ShipStrategy</tt> set, which is not equal to <tt>NONE</tt>.
*
* @param n
* The node to compute the costs for.
*/
public void costOperator(OptimizerNode n) {
if (n.getIncomingConnections() == null) {
throw new CompilerException("Cannot compute costs on operator before incoming connections are set.");
}
// initialize costs objects with currently unknown costs
Costs globCost = new Costs();
Costs locCost = new Costs();
globCost.setNetworkCost(0);
globCost.setSecondaryStorageCost(0);
List<PactConnection> incomingConnections = n.getIncomingConnections();
for (int i = 0; i < incomingConnections.size(); i++) {
PactConnection connection = incomingConnections.get(i);
Costs tempGlobalCost = new Costs();
switch (connection.getShipStrategy().type()) {
case NONE:
throw new CompilerException(
"Cannot determine costs: Shipping strategy has not been set for an input.");
case FORWARD:
case PARTITION_LOCAL_HASH:
tempGlobalCost.setNetworkCost(0);
tempGlobalCost.setSecondaryStorageCost(0);
break;
case PARTITION_HASH:
getHashPartitioningCost(connection, tempGlobalCost);
break;
case PARTITION_RANGE:
getRangePartitionCost(connection, tempGlobalCost);
break;
case BROADCAST:
getBroadcastCost(connection, tempGlobalCost);
break;
case SFR:
throw new CompilerException("Symmetric-Fragment-And-Replicate Strategy currently not supported.");
default:
throw new CompilerException("Unknown shipping strategy for input: " + connection.getShipStrategy().name());
}
globCost.addCosts(tempGlobalCost);
}
PactConnection primConn = null;
PactConnection secConn = null;
// get the inputs, if we have some
{
if (incomingConnections.size() > 0) {
primConn = incomingConnections.get(0);
}
if (incomingConnections.size() > 1) {
secConn = incomingConnections.get(1);
}
}
// determine the local costs
locCost.setNetworkCost(0);
switch (n.getLocalStrategy()) {
case NONE:
locCost.setNetworkCost(0);
locCost.setSecondaryStorageCost(0);
break;
case COMBININGSORT:
case SORT:
getLocalSortCost(n, primConn, locCost);
break;
case SORT_BOTH_MERGE:
getLocalDoubleSortMergeCost(n, primConn, secConn, locCost);
break;
case SORT_FIRST_MERGE:
getLocalSingleSortMergeCost(n, primConn, secConn, locCost);
break;
case SORT_SECOND_MERGE:
getLocalSingleSortMergeCost(n, secConn, primConn, locCost);
break;
case MERGE:
getLocalMergeCost(n, primConn, secConn, locCost);
break;
case SORT_SELF_NESTEDLOOP:
getLocalSortSelfNestedLoopCost(n, primConn, 10, locCost);
break;
case SELF_NESTEDLOOP:
getLocalSelfNestedLoopCost(n, primConn, 10, locCost);
break;
case HYBRIDHASH_FIRST:
getHybridHashCosts(n, primConn, secConn, locCost);
break;
case HYBRIDHASH_SECOND:
getHybridHashCosts(n, secConn, primConn, locCost);
break;
case MMHASH_FIRST:
getMainMemHashCosts(n, primConn, secConn, locCost);
break;
case MMHASH_SECOND:
getMainMemHashCosts(n, secConn, primConn, locCost);
break;
case NESTEDLOOP_BLOCKED_OUTER_FIRST:
getBlockNestedLoopsCosts(n, primConn, secConn, BlockResettableMutableObjectIterator.MIN_BUFFER_SIZE, locCost);
break;
case NESTEDLOOP_BLOCKED_OUTER_SECOND:
getBlockNestedLoopsCosts(n, secConn, primConn, BlockResettableMutableObjectIterator.MIN_BUFFER_SIZE, locCost);
break;
case NESTEDLOOP_STREAMED_OUTER_FIRST:
getStreamedNestedLoopsCosts(n, primConn, secConn,
128 * 1024, locCost);
break;
case NESTEDLOOP_STREAMED_OUTER_SECOND:
getStreamedNestedLoopsCosts(n, secConn, primConn,
128 * 1024, locCost);
break;
default:
throw new CompilerException("Unknown local strategy: " + n.getLocalStrategy().name());
}
// add the costs and set them
globCost.addCosts(locCost);
n.setCosts(globCost);
}
}