Commit 034cd782 authored by uahhx's avatar uahhx

sync

TODO:
implement message rejection, dropping by strategy
make strategy objects per node because they need per node info
parent 66015392
......@@ -3,19 +3,26 @@ package FunnelNetSim;
public class DataPacket {
private messageType mType;
private int originNode;
private static int packetID = 0; //just for behavioral evaluation
private static int packetIDCounter = 0; //just for behavioral evaluation (beeva)
private int packetID;
private int latencyCounter;
private boolean processed; //just for beeva
//private boolean isControlPacket; //might want to implement just unsing a bool later on, for info it might be better to use the enum though
public enum messageType {
REGULAR, STOPSTART
}
public enum messageState {
UNPROCESSED, PROCESSED, REJECTED, OUTDATED, DROPPED
}
public DataPacket(int originNode, messageType mType) {
this.originNode = originNode;
this.mType = mType;
this.packetID = mType == messageType.REGULAR ? packetID++ : -1;
this.packetID = mType == messageType.REGULAR ? packetIDCounter++ : -1;
resetLatencyCounter();
processed = false;
}
public messageType getMType() {
......@@ -38,4 +45,16 @@ public class DataPacket {
//latencyCounter--;
return --latencyCounter <= 0;
}
public void markProcessed() {
processed = true;
}
public boolean isProcessed() {
return processed;
}
public int getPacketID() {
return packetID;
}
}
......@@ -12,6 +12,7 @@ public class FunnelNet {
public static final Strategy strat = new TestStrategy();
private int cycleCounter = 0;
public static final boolean verbose = true;
public static final int packetLatency = 1; //in cycles
public static final int controlPacketSize = 1; //for slinkyBuffer. warning: if this changes from 1, handling of sending multiple segments has to be implemented
......@@ -25,10 +26,10 @@ public class FunnelNet {
private static int numLayers; //0 based!
private static final int minNetLayers = 5;
private MasterNode master = null;
private HashSet<NetNode> netNodes = new HashSet<NetNode>();
private HashSet<SlaveNode> slavesNodes = new HashSet<SlaveNode>();
private HashSet<Node> allNodes = new HashSet<Node>();
public MasterNode master = null;
public HashSet<NetNode> netNodes = new HashSet<NetNode>();
public HashSet<SlaveNode> slavesNodes = new HashSet<SlaveNode>();
public HashSet<Node> allNodes = new HashSet<Node>();
public static int packetCounter = 0;
......@@ -41,6 +42,7 @@ public class FunnelNet {
private void createNet() {
int layerNumber = 0;
master = new MasterNode(layerNumber, 0);
master.setSuperNeighbor(null);
HashSet<Node> curLayerNodes = new HashSet<Node>();
curLayerNodes.add(master);
......@@ -73,7 +75,7 @@ public class FunnelNet {
}
private void createSlaveLayer(int numNewNodes, int layerNumber, HashSet<Node> prevLayerNodes) {
numLayers = layerNumber;
numLayers = layerNumber+1;
int numClusters = prevLayerNodes.size();
//int funnelWidth = numClusters*numDownConnections;
......@@ -90,6 +92,7 @@ public class FunnelNet {
for (int i = 0; i < newSlaveNodes.length; i++) {
SlaveNode curNewNode = new SlaveNode(layerNumber, curNode.getNodeNumber()*numNewNodes+i);
curNewNode.setSuperNeighbor(curNode);
curNewNode.setSubNeighbors(new Node[0]);
newSlaveNodes[i] = curNewNode;
slavesNodes.add(curNewNode);
nextLayerNodes.add(curNewNode);
......@@ -105,11 +108,16 @@ public class FunnelNet {
return numLayers;
}
public int getCycleCounter() {
return cycleCounter;
}
public int tickNet() {
cycleCounter++;
for(Node curNode : allNodes)
curNode.preTick();
curNode.updateLines();
for(Node curNode : allNodes)
curNode.tick();
return cycleCounter++;
return cycleCounter;
}
}
......@@ -7,14 +7,20 @@ public class MasterNode extends Node {
}
@Override
public void preTick() {
public void updateLines() {
updateSubLines();
}
@Override
public void tick() {
// TODO Auto-generated method stub
super.tick();
//select receive element
superIncoming = selectFromFrontRow(); //uses the superIncoming variable because downwardCom refers to it. /should/ run smoothly. TODO: make sure this actually does run smoothly
if (superIncoming != null)
superIncoming.markProcessed();
downwardCom();
//send element back
}
}
......@@ -8,15 +8,18 @@ public class NetNode extends Node {
}
@Override
public void preTick() {
public void updateLines() {
updateSuperLine();
updateSubLines();
}
@Override
public void tick() {
// TODO Auto-generated method stub
super.tick();
send(selectFromFrontRow(), superNeighbor);
downwardCom();
}
}
......@@ -17,14 +17,14 @@ public abstract class Node {
protected ArrayList<SlinkyBuffer<DataPacket>> superBuffers;
private LinkedList<DataPacket> superIncomingLine;
private DataPacket superIncoming;
protected DataPacket superIncoming;
private ArrayList<SlinkyBuffer<DataPacket>> subBuffers;
protected ArrayList<SlinkyBuffer<DataPacket>> subBuffers;
private ArrayList<LinkedList<DataPacket>> subIncomingLines;
private DataPacket[] subIncoming;
protected DataPacket[] subIncoming;
//subFirstElement could be skipped by putting the incomings into the buffer and immediatly reading them from there,
//but muliplexing incomings and buffered data is to emulate how the hardware would work and make code adaptation easier
private DataPacket[] subFrontRow;
protected DataPacket[] subFrontRow;
protected boolean superSendEnableS; //this is >received< from super. S for slave
private boolean[] subSendEnableM; //this is >sent< to subs. M for master
......@@ -43,13 +43,18 @@ public abstract class Node {
this.superSendEnableS = true; //initially this node is able to send
}
public Node getSuperNeighbor() {
return superNeighbor;
}
public void setSubNeighbors(Node[] subNeighbors) {
this.subNeighbors = subNeighbors;
this.subIncoming = new DataPacket[subNeighbors.length];
this.subFrontRow = new DataPacket[subNeighbors.length];
this.subSendEnableM = new boolean[subNeighbors.length];
this.subBuffers = new ArrayList<SlinkyBuffer<DataPacket>>(subNeighbors.length);
this.subIncomingLines = new ArrayList<LinkedList<DataPacket>>();
this.subIncomingLines = new ArrayList<LinkedList<DataPacket>>(subNeighbors.length);
this.superBuffers = new ArrayList<SlinkyBuffer<DataPacket>>(subNeighbors.length);
for (int i = 0; i < subNeighbors.length; i++) {
subBuffers.add(new SlinkyBuffer<DataPacket>());
......@@ -60,8 +65,21 @@ public abstract class Node {
}
public Node[] getSubNeighbors() {
return subNeighbors;
}
public void listTree() {
Node curNode;
System.out.println("Layer: " + layerNumber + ", Number: " + nodeNumber + ", Node: " + this.toString());
if(subNeighbors != null)
for (int i = 0; i < subNeighbors.length; i++)
subNeighbors[i].listTree();
}
//handle incoming data. call all nodes pretick before tick to keep things "parallel"
public abstract void preTick();
public abstract void updateLines();
protected void updateSuperLine() {
superIncoming = updateLine(superIncomingLine);
......@@ -102,7 +120,12 @@ public abstract class Node {
}
protected void upwardCom() { //warning: this code is just for net nodes afaict
/**
* Builds an array containing the first elements of all incoming lines, returns the DataPacket selected by the set strategy
* Removes the selected DataPacket from its source in the process!
* @return DataPacket selected for forwarding by the set strategy
*/
protected DataPacket selectFromFrontRow() {
for (int i = 0; i < subNeighbors.length; i++) {
if (subBuffers.get(i).isEmpty())
subFrontRow[i] = subIncoming[i];
......@@ -112,11 +135,14 @@ public abstract class Node {
int subSelect = FunnelNet.strat.selectForwardingSub(subFrontRow);
send(subFrontRow[subSelect], superNeighbor);
if(subBuffers.get(subSelect).isEmpty())
subIncoming[subSelect] = null;
else
subBuffers.get(subSelect).takeFromBuffer();
if(subSelect >= 0) {
if(subBuffers.get(subSelect).isEmpty())
subIncoming[subSelect] = null;
else
subBuffers.get(subSelect).takeFromBuffer();
}
return (subSelect >= 0 && subSelect < subFrontRow.length) ? subFrontRow[subSelect] : null;
}
......@@ -136,19 +162,17 @@ public abstract class Node {
curSubBuf.add(subIncoming[i]);
if (curSubBuf.limitReached() == subSendEnableM[i]) { //if the limit is reached and the sub is currently allowed to send (or vice versa), send control packet
subSendEnableM[i] = !curSubBuf.limitReached();
selectedMessage = new DataPacket(-1, DataPacket.messageType.STOPSTART); //send StartStop K-Flagged segment.
send(new DataPacket(-1, DataPacket.messageType.STOPSTART), subNeighbors[i]); //send StartStop K-Flagged segment.
}
//TODO: insert rejection method here
else if (!curSuperBuf.isEmpty() || superIncDest == i) {
selectedMessage = curSuperBuf.isEmpty() ? superIncoming : curSuperBuf.takeFromBuffer();
send(curSuperBuf.isEmpty() ? superIncoming : curSuperBuf.takeFromBuffer(), subNeighbors[i]);
if (!curSuperBuf.isEmpty() && superIncDest == i) {
curSuperBuf.add(superIncoming);
if (curSuperBuf.limitReached())
System.out.println("a superbuffer ran over! this should not be happening!"); //NOTE: use this <PLACE> to check super buffer fill state later (implement buffer.size())
}
}
else
selectedMessage = null;
send(selectedMessage, subNeighbors[i]);
}
}
......@@ -157,20 +181,23 @@ public abstract class Node {
}*/
private int getLocalOrigin(int globalOrigin) {
return globalOrigin / (int)Math.pow(FunnelNet.numDownConnections, FunnelNet.getNumLayers() - layerNumber); //TODO: make sure the power is correct
return globalOrigin / (int)Math.pow(FunnelNet.numDownConnections, FunnelNet.getNumLayers() - 1 - layerNumber); //TODO: make sure the power is correct
}
public void send(DataPacket message, Node target) {
target.receive(message, this);
if (message != null && target != null)
target.receive(message, this);
}
/**
* This Node receives a DataPacket from source Node. Won't be forwarded to the logic until the lines are updated again, aka the next global cycle.
* @param message
* @param source
*/
public void receive(DataPacket message, Node source) {
boolean fromSub = false;
int subNumber = -1;
if (source == superNeighbor) {
fromSub = true;
subNumber = getLocalOrigin(message.getOrigin());
}
int subNumber = -2;
if (source == superNeighbor)
subNumber = -1;
else {
for (int i = 0; i < subNeighbors.length; i++)
if (subNeighbors[i] == source) {
......@@ -179,7 +206,9 @@ public abstract class Node {
}
}
receive(message, subNumber, fromSub);
if (subNumber <= -2)
System.out.println("Sending node is not connected to receiving node.");
receive(message, subNumber);
}
......@@ -187,17 +216,22 @@ public abstract class Node {
* This exists to afford the ability to forcefully inject datapackets into the node.
* @param message
* @param subNumber
* @param fromSub
*/
public void receive(DataPacket message, int subNumber, boolean fromSub) {
if (subNumber == -1) {
public void receive(DataPacket message, int subNumber) {
if (subNumber == -2) {
System.out.println("Received Message from an unconnected source!");
return;
}
LinkedList<DataPacket> incomingLine = fromSub ? subIncomingLines.get(subNumber) : superIncomingLine;
LinkedList<DataPacket> incomingLine = subNumber < 0 ? superIncomingLine : subIncomingLines.get(subNumber);
message.resetLatencyCounter();
incomingLine.addFirst(message);
if (FunnelNet.verbose)
System.out.println(nodeID() + " received Message no. " + message.getPacketID() + " from " + (subNumber < -1 ? "unconnected" : (subNumber == -1 ? superNeighbor.nodeID() : (subNumber >= 0 ? subNeighbors[subNumber].nodeID() : subNumber))));
}
public String nodeID() {
return layerNumber + ":" + nodeNumber + " " + this.toString();
}
public void setLayerNumber(int num) {
......
......@@ -10,21 +10,21 @@ public class SlaveNode extends Node {
}
@Override
public void preTick() {
public void updateLines() {
updateSuperLine();
}
@Override
public void tick() {
// TODO Auto-generated method stub
//super.tick();
tick(false);
super.tick();
if (superIncoming != null)
System.out.println("Message no. " + superIncoming.getPacketID() + " from " + superIncoming.getOrigin() + " returned to " + getNodeNumber());
}
public void tick(boolean spawnPacket) {
tick();
if(spawnPacket && !createPacket())
System.out.println("couldn't spawn packet");
}
public boolean createPacket() {
......@@ -34,5 +34,6 @@ public class SlaveNode extends Node {
return true;
}
return false;
}
}
package FunnelNetSim;
import FunnelNetSim.Nodes.Node;
import FunnelNetSim.Nodes.SlaveNode;
import FunnelNetSim.Strategies.TestStrategy;
public class SimHost {
public static void main(String[] args) {
run();
}
private static void run() {
FunnelNet net = new FunnelNet();
net.master.listTree();
int a = 2;
int b = 5;
int c = 30;
for (int i = 0; i < a; i++) {
System.out.println(net.tickNet());
}
for (int i = a; i < b; i++) {
for (SlaveNode slave : net.slavesNodes) {
slave.createPacket();
}
System.out.println(net.tickNet());
}
for (int i = 0; i < 42; i++) {
for (int i = b; i < c; i++) {
System.out.println(net.tickNet());
}
}
......
......@@ -6,4 +6,8 @@ public interface Strategy {
public int selectForwardingSub(DataPacket[] frontRow);
//public boolean shouldReject(DataPacket[] frontRow);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment