package com.chinamobile.bcbsp.examples.pagerank;
/**
* PageRankBSP.java
*/
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.chinamobile.bcbsp.api.BSP;
import com.chinamobile.bcbsp.api.Edge;
import com.chinamobile.bcbsp.bspstaff.BSPStaffContextInterface;
import com.chinamobile.bcbsp.bspstaff.Staff;
import com.chinamobile.bcbsp.bspstaff.SuperStepContextInterface;
import com.chinamobile.bcbsp.comm.BSPMessage;
/**
* PageRankBSP.java
* This is the user-defined arithmetic which implements {@link BSP}.
*
* @author WangZhigang
* @version 0.1 2012-2-17
*/
public class PageRankBSP extends BSP {
public static final Log LOG = LogFactory.getLog(PageRankBSP.class);
public static final String ERROR_SUM = "aggregator.error.sum";
public static final double ERROR_THRESHOLD = 0.1;
public static final double CLICK_RP = 0.0001;
public static final double FACTOR = 0.15;
// Variables of the Graph.
private float newVertexValue = 0.0f;
private float receivedMsgValue = 0.0f;
private float receivedMsgSum = 0.0f;
private float sendMsgValue = 0.0f;
@SuppressWarnings("unchecked")
private Iterator<Edge> outgoingEdges;
private PREdgeLite edge;
private BSPMessage msg;
private ErrorAggregateValue errorValue;
private int failCounter = 0;
@Override
public void setup(Staff staff) {
this.failCounter = staff.getFailCounter();
LOG.info("Test FailCounter: " + this.failCounter);
}
@Override
public void compute(Iterator<BSPMessage> messages, BSPStaffContextInterface context)
throws Exception {
// Receive messages sent to this Vertex.
receivedMsgValue = 0.0f;
receivedMsgSum = 0.0f;
while (messages.hasNext()) {
receivedMsgValue = Float.parseFloat(new String(messages.next().getData()));
receivedMsgSum += receivedMsgValue;
}
PRVertexLite vertex = (PRVertexLite) context.getVertex();
// Just for creating a fault manually.
if (context.getCurrentSuperStepCounter() == 7 && vertex.getVertexID() == 3858241 && this.failCounter < 3) {
LOG.error("Fault manually : <VertexID>" + vertex.getVertexID());
throw new Exception(vertex.getVertexID().toString());
}
// Handle received messages and Update vertex value.
if (context.getCurrentSuperStepCounter() == 0) {
sendMsgValue = Float.valueOf(vertex.getVertexValue())/context.getOutgoingEdgesNum(); // old vertex value
} else {
// According to the sum of error to judge the convergence.
errorValue = (ErrorAggregateValue)context.getAggregateValue(ERROR_SUM);
if (Double.parseDouble(errorValue.getValue()) < ERROR_THRESHOLD) {
context.voltToHalt();
return;
}
newVertexValue = (float) (CLICK_RP * FACTOR + receivedMsgSum * (1 - FACTOR));
sendMsgValue = newVertexValue / context.getOutgoingEdgesNum();
vertex.setVertexValue(newVertexValue);
context.updateVertex(vertex);
}
// Send new messages.
outgoingEdges = context.getOutgoingEdges();
while (outgoingEdges.hasNext()) {
edge = (PREdgeLite) outgoingEdges.next();
msg = new BSPMessage(String.valueOf(edge.getVertexID()),
Float.toString(sendMsgValue).getBytes());
context.send(msg);
}
return;
}
@Override
public void initBeforeSuperStep(SuperStepContextInterface arg0) {
}
}