瀏覽代碼

Improves ConnectionPrecision performance (n^2->nlogn)

* TreeSet instead of SelfSorting List
* Iterations with million packets/seconds working fine now
* No longer possible to generate packets earlier than the last generated
packet per port
Andreas T. Meyer-Berg 5 年之前
父節點
當前提交
55542983e1

+ 2 - 2
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPerformance.java

@@ -97,10 +97,10 @@ public class ConnectionPerformance implements Connection {
 		returnPackets.addAll(getTerminationPackages(startTime));
 		for(Port p:participants){
 			if(p.getLastTrigger()+p.getTriggerInterval()<startTime && p.getStatus()==Port.SENDING){
-				returnPackets.addAll(protocol.generateNextPakets(p, (long) (startTime+p.getJitter()*Math.random()/2),Math.random()<packetLossRate));
+				returnPackets.addAll(protocol.generateNextPakets(p, (long) (startTime+p.getJitter()*Math.random()),Math.random()<packetLossRate));
 			}
 			while(p.getLastTrigger()+p.getTriggerInterval()<startTime+duration &&p.getStatus()==Port.SENDING)
-				returnPackets.addAll(protocol.generateNextPakets(p, (long) (p.getLastTrigger()+p.getTriggerInterval()+p.getJitter()*(Math.random()-0.5)),Math.random()<packetLossRate));
+				returnPackets.addAll(protocol.generateNextPakets(p, (long) Math.max((p.getLastTrigger()+p.getTriggerInterval()+p.getJitter()*(Math.random())),p.getLastTrigger()+p.getTriggerInterval()+1),Math.random()<packetLossRate));
 		}
 		returnPackets.sort((a,b)->(Long.compare(a.getTimestamp(),b.getTimestamp())));
 		return returnPackets;

+ 30 - 57
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/ConnectionPrecision.java

@@ -2,8 +2,9 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.core;
 
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.LinkedList;
-import java.util.ListIterator;
+import java.util.TreeSet;
 
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.util.PacketComparator;
 
@@ -56,73 +57,45 @@ public class ConnectionPrecision extends ConnectionPerformance {
 		returnPackets.addAll(outOfBoundsPackets);
 		
 		/**
-		 * Self Sorting LinkedList for consistency
+		 * Sorted Tree (Sorted by next trigger time)
 		 */
-		LinkedList<Port> list = new LinkedList<Port>();
-		list.addAll(participants);
-		//Sort by next trigger time step
-		list.sort(new PortComparator());
-		
-		/*
-		 * Packages that should have been sent before the simulation time step
+		java.util.TreeSet<Port> portTree = new TreeSet<Port>(new PortComparator());
+		portTree.addAll(participants);
+
+		/**
+		 * Iterator to move through the Tree
 		 */
+		Iterator<Port> it = portTree.iterator();
+		
 		/**
-		 * Iterator to move through the list
+		 * Traverse the tree ascending
 		 */
-		ListIterator<Port> it = list.listIterator();
-		boolean packageBeforeInterval = false;
-		while(it.hasNext()){
-			Port p = it.next();
-			if(p.getLastTrigger()+p.getTriggerInterval()<startTime){
-				if(p.getStatus()==Port.SENDING){
-					//Generate first package in the simulation interval
-					returnPackets.addAll(protocol.generateNextPakets(p, (long) (startTime+p.getJitter()*Math.random()/2),Math.random()<packetLossRate));
-					packageBeforeInterval = true;
-					startTime++;
-				}
-			}else{
-				//If not further calculations before the interval are required
-				break;
-			}
-		}
-		//If next package steps changed -> sort again (should occur rarely/never)
-		if(packageBeforeInterval)
-			list.sort(new PortComparator());
-		//Generate packages
-		it = list.listIterator();
 		while(it.hasNext()){
 			Port p = it.next();
 			
-			if(p.getStatus()==Port.SENDING){
-				if(p.getLastTrigger()+p.getTriggerInterval()<endTime){
-					//Generate first package in the simulation interval (not before startTime though)
-					returnPackets.addAll(protocol.generateNextPakets(p, Math.max((long) (p.getLastTrigger()+p.getTriggerInterval()+p.getJitter()*(Math.random()-0.5)),startTime),Math.random()<packetLossRate));
-
-					//Remove Ports, which won't simulate again during this time step
+			if(p.getStatus()==Port.SENDING && p.getLastTrigger()+p.getTriggerInterval()<endTime){
+					/**
+					 * Remove current Port (as the nextTrigger time will change, and therefore its position in the tree)
+					 */
 					it.remove();
-					//If further packages should be generated -> move inside the list
+					/**
+					 * Generate first package in the simulation interval (not before startTime though), and at least 1ms after the last Trigger Time
+					 */
+					returnPackets.addAll(protocol.generateNextPakets(p, (long)Math.max( p.getLastTrigger()+p.getTriggerInterval()+p.getJitter()*Math.random(),Math.max(p.getLastTrigger()+1,startTime)),Math.random()<packetLossRate));
+					/**
+					 * If Port should simulate again in this interval -> add back to the tree
+					 */
 					if(p.getLastTrigger()+p.getTriggerInterval()<endTime){
-						//move Port to it's new Position;
-						boolean added = false;
-						while(it.hasNext()){
-							Port next = it.next();
-							if(new PortComparator().compare(p, next)<0){
-								//Insert in front of this Port
-								it.add(p);
-								added = true;
-							}
-						}
-						if(!added){
-							//Add as last element
-							it.add(p);
-						}
-						it = list.listIterator();
+						portTree.add(p);
+						/**
+						 * Reset iterator, to start from the next simulating port
+						 */
+						it = portTree.iterator();
 					}
-				}else{
-					it.remove();
-				}
 			}else{
-				//Remove ports, which are not sending
+				/**
+				 * Remove ports, which are not sending or which won't simulate in this interval again
+				 */
 				it.remove();
 			}
 		}