/*******************************************************************************
* Copyright (c) 2014 Imperial College London
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Raul Castro Fernandez - initial API and implementation
******************************************************************************/
package uk.ac.imperial.lsds.java2sdg.bricks.SDG;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import uk.ac.imperial.lsds.java2sdg.bricks.TaskElement;
public class OperatorBlock {
private final int id;
private final int workflowId;
private final boolean stateful;
private int stateId;
private List<TaskElement> taskElements;
private List<Stream> downstreamOperator;
private List<Stream> upstreamOperator;
private String finalCode = null;
public void setCode(String code) throws Exception{
//this.finalCode = finalCode == null ? code : finalCode;
// If it was previously assigned
if(this.finalCode != null){
throw new Exception("Code in operatorBlock can only be set once");
}
else{
this.finalCode = code;
}
}
public String getCode(){
return finalCode;
}
// Keeps the relation between a streamId<String> and a TE<TaskElement>
private Map<Integer, TaskElement> branchingId_TE;
private OperatorBlock(int id, int workflowId, int stateId, boolean stateful){
this.id = id;
this.workflowId = workflowId;
this.stateful = stateful;
this.stateId = stateId;
this.taskElements = new ArrayList<TaskElement>();
this.downstreamOperator = new ArrayList<Stream>();
this.upstreamOperator = new ArrayList<Stream>();
this.branchingId_TE = new HashMap<Integer, TaskElement>();
}
public void associateBranchingIdWithTE(int branchingIdentifier, TaskElement te){
this.branchingId_TE.put(branchingIdentifier, te);
}
public int getId(){
return id;
}
public int getWorkflowId(){
return workflowId;
}
public int getStateId(){
return stateId;
}
public static OperatorBlock makeStatefulOperator(int id, int workflowId, int stateId){
return new OperatorBlock(id, workflowId, stateId, true);
}
public static OperatorBlock makeStatelessOperator(int id, int workflowId, int stateId){
return new OperatorBlock(id, workflowId, stateId, false);
}
public void addTE(TaskElement te, int id, int workflowId){
// We add the TE to the collection
this.taskElements.add(te);
// Set up the branchingID
// where branchingId == workflowId
branchingId_TE.put(workflowId, te);
}
public TaskElement getTE(){
if(taskElements.size() >= 1)
return this.taskElements.get(0);
else{
return null;
}
}
public List<TaskElement> getTEs(){
return taskElements;
}
public void addDownstream(int id, int workflowId, StreamType type){
Stream s = new Stream(id, workflowId, type);
downstreamOperator.add(s);
}
public List<Stream> getDownstreamOperator(){
return downstreamOperator;
}
public int getDownstreamSize(){
return downstreamOperator.size();
}
public List<Stream> getUpstreamOperator(){
return upstreamOperator;
}
public int getUpstreamSize(){
return upstreamOperator.size();
}
public void addUpstream(int id, int workflowId){
Stream s = new Stream(id, workflowId, StreamType.UPSTREAM);
upstreamOperator.add(s);
}
public void reconfigureDownstream(int prevId, int prevWorkflowId, int newId, int newWorkflowId){
StreamType st = null; // We want to just propagate the stream type. There is no reconf option here
Iterator<Stream> down = downstreamOperator.iterator();
while(down.hasNext()){
Stream d = down.next();
// Detect old stream and remove it
if(d.getId() == prevId && d.getWorkflowId() == prevWorkflowId){
st = d.getType();
down.remove();
}
}
// Create new stream
this.addDownstream(newId, newWorkflowId, st);
}
public void reconfigureUpstream(int prevId, int prevWorkflowId, int newId, int newWorkflowId){
Iterator<Stream> up = upstreamOperator.iterator();
while(up.hasNext()){
Stream d = up.next();
// Detect old stream and remove it
if(d.getId() == prevId && d.getWorkflowId() == prevWorkflowId){
up.remove();
}
}
// Create new stream
this.addUpstream(newId, newWorkflowId);
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("\n");
sb.append("--> OB - "+this.id+" from workflow: "+this.workflowId+"\n");
if(this.stateful){
sb.append("Stateful - "+this.stateId+"\n");
}
else{
sb.append("Stateless \n");
}
sb.append("#TEs: "+this.taskElements.size()+"\n");
for(Integer branchId : branchingId_TE.keySet()){
sb.append("TE attached to branchId: "+branchId);
sb.append("\n");
TaskElement te = branchingId_TE.get(branchId);
sb.append(te);
sb.append("\n");
}
// for(int i = 0; i < this.taskElements.size(); i++){
// sb.append("\n");
// sb.append("TE attached to branchId: ");
// sb.append(this.taskElements.get(i));
// sb.append("\n");
// }
StringBuilder sbdown = new StringBuilder();
sbdown.append("[");
for(Stream s : downstreamOperator){
sbdown.append(s.getId()+"-"+s.getWorkflowId()+", ");
}
sbdown.append("]");
sb.append("#Downstream: "+sbdown.toString()+"\n");
StringBuilder sbup = new StringBuilder();
sbup.append("[");
for(Stream s : upstreamOperator){
sbup.append(s.getId()+"-"+s.getWorkflowId()+", ");
}
sbup.append("]");
sb.append("#Upstream: "+sbup.toString()+"\n");
return sb.toString();
}
}