From ccde6a9668bc7cdd016b1db170d745371ba7bcec Mon Sep 17 00:00:00 2001 From: Berack96 Date: Fri, 17 Jan 2025 12:40:18 +0100 Subject: [PATCH] JavaDoc added --- .../java/net/berack/upo/valpre/Event.java | 25 +++++++ .../net/berack/upo/valpre/NetSimulation.java | 69 +++++++++++++++++++ .../net/berack/upo/valpre/ServerNode.java | 38 ++++++++++ .../berack/upo/valpre/rand/Distribution.java | 26 +++++++ 4 files changed, 158 insertions(+) diff --git a/src/main/java/net/berack/upo/valpre/Event.java b/src/main/java/net/berack/upo/valpre/Event.java index 316983a..b789d9f 100644 --- a/src/main/java/net/berack/upo/valpre/Event.java +++ b/src/main/java/net/berack/upo/valpre/Event.java @@ -1,16 +1,26 @@ package net.berack.upo.valpre; +/** + * Represents an event in the simulation. + */ public class Event implements Comparable { public final double time; public final Type type; public final ServerNode node; + /** + * Create a new event. + * @param type The type of event. + * @param node The node that the event is associated with. + * @param time The time at which the event occurs. + */ private Event(Type type, ServerNode node, double time) { this.type = type; this.time = time; this.node = node; } + @Override public int compareTo(Event other) { if (this.time < other.time) return -1; @@ -19,14 +29,29 @@ public class Event implements Comparable { return 1; } + /** + * Create a new arrival event. + * @param node The node that the event is associated with. + * @param time The time at which the event occurs. + * @return The new event. + */ public static Event newArrival(ServerNode node, double time) { return new Event(Type.ARRIVAL, node, time); } + /** + * Create a new departure event. + * @param node The node that the event is associated with. + * @param time The time at which the event occurs. + * @return The new event. + */ public static Event newDeparture(ServerNode node, double time) { return new Event(Type.DEPARTURE, node, time); } + /** + * The type of event. + */ public static enum Type { ARRIVAL, DEPARTURE, diff --git a/src/main/java/net/berack/upo/valpre/NetSimulation.java b/src/main/java/net/berack/upo/valpre/NetSimulation.java index 8c4b348..6df5f3b 100644 --- a/src/main/java/net/berack/upo/valpre/NetSimulation.java +++ b/src/main/java/net/berack/upo/valpre/NetSimulation.java @@ -6,20 +6,43 @@ import java.util.Map; import java.util.PriorityQueue; import net.berack.upo.valpre.rand.Rng; +/** + * A network simulation that uses a discrete event simulation to model the + * behavior of a network of servers. + */ public class NetSimulation { public final long seed; private final Rng rng; private final Map servers = new HashMap<>(); + /** + * Creates a new network simulation with the given seed. + * + * @param seed The seed to use for the random number generator. + */ public NetSimulation(long seed) { this.seed = seed; this.rng = new Rng(seed); } + /** + * Adds a new server node to the network. + * + * @param node The server node to add. + */ public void addNode(ServerNode node) { this.servers.put(node.name, node); } + /** + * Runs the simulation for the given number of total arrivals, stopping when the + * given node has reached the + * specified number of departures. + * + * @param total The total number of arrivals to simulate. + * @param untilDepartureNode The name of the node to stop at. + * @return A map of statistics for each server node in the network. + */ public Map run(long total, String untilDepartureNode) { // Initialization var timeNow = 0.0d; @@ -49,6 +72,12 @@ public class NetSimulation { return stats; } + /** + * Represents a statistical summary of the behavior of a server node in the + * network. + * It is used by the simulation to track the number of arrivals and departures, + * the maximum queue length, the busy time, and the response time. + */ public static class Statistics { public int numArrivals = 0; public int numDepartures = 0; @@ -61,10 +90,18 @@ public class NetSimulation { private ArrayDeque queue = new ArrayDeque<>(); private final Rng rng; + /** + * Creates a new statistics object with the given random number generator. + * + * @param rng The random number generator to use. + */ public Statistics(Rng rng) { this.rng = rng; } + /** + * Resets the statistics to their initial values. + */ public void reset() { this.numArrivals = 0; this.numDepartures = 0; @@ -74,6 +111,17 @@ public class NetSimulation { this.queue.clear(); } + /** + * Processes an arrival event for the given node at the given time. + * The event is processed by adding the arrival time to the queue, updating the + * maximum queue length, and checking if a server is available to process the + * arrival. If a server is available, a departure event is created and added to + * the future event list. + * + * @param event The arrival event to process. + * @param timeNow The current time of the simulation. + * @param fel The future event list to add new events to. + */ private void processArrival(Event event, double timeNow, PriorityQueue fel) { this.numArrivals++; this.queue.add(event.time); @@ -92,6 +140,18 @@ public class NetSimulation { this.addArrivalIf(event.node.isSource, event.node, timeNow, fel); } + /** + * Processes a departure event for the given node at the given time. + * The event is processed by removing the departure time from the queue, + * updating the busy time, and checking if there are any arrivals in the queue. + * If there are, a new departure event is created and added to the fel. + * At the end it will add an arrival to the next node if the current node has a + * child. + * + * @param event The departure event to process. + * @param timeNow The current time of the simulation. + * @param fel The future event list to add new events to. + */ private void processDeparture(Event event, double timeNow, PriorityQueue fel) { var startService = this.queue.poll(); var response = timeNow - startService; @@ -113,6 +173,15 @@ public class NetSimulation { this.addArrivalIf(!event.node.isSink, next, timeNow, fel); } + /** + * Adds an arrival event to the future event list if the given condition is + * true. + * + * @param condition The condition to check. + * @param node The node to add the arrival event for. + * @param timeNow The current time of the simulation. + * @param fel The future event list to add the event to. + */ private void addArrivalIf(boolean condition, ServerNode node, double timeNow, PriorityQueue fel) { if (condition && node != null) { var delay = node.distribution.sample(this.rng); diff --git a/src/main/java/net/berack/upo/valpre/ServerNode.java b/src/main/java/net/berack/upo/valpre/ServerNode.java index 241ee7c..24a3b14 100644 --- a/src/main/java/net/berack/upo/valpre/ServerNode.java +++ b/src/main/java/net/berack/upo/valpre/ServerNode.java @@ -5,6 +5,10 @@ import java.util.List; import net.berack.upo.valpre.rand.Distribution; import net.berack.upo.valpre.rand.Rng; +/** + * Represents a node in the network. It can be a source, a queue, or a sink + * based on the configuration passed as parameters. + */ public class ServerNode { public final String name; public final int maxServers; @@ -14,14 +18,35 @@ public class ServerNode { private final List children = new ArrayList<>(); private double sumProbabilities = 0.0; + /** + * Creates a source node with the given name and distribution. + * @param name The name of the node. + * @param distribution The distribution of the inter-arrival times. + * @return The created source node. + */ public static ServerNode createSource(String name, Distribution distribution) { return new ServerNode(name, Integer.MAX_VALUE, distribution, false, true); } + /** + * Creates a queue node with the given name, maximum number of servers, and distribution. + * @param name The name of the node. + * @param maxServers The maximum number of servers in the queue. + * @param distribution The distribution of the service times. + * @return The created queue node. + */ public static ServerNode createQueue(String name, int maxServers, Distribution distribution) { return new ServerNode(name, maxServers, distribution, false, false); } + /** + * Creates a generic node with the given name and distribution. + * @param name The name of the node. + * @param maxServers The maximum number of servers in the queue. + * @param distribution The distribution of the service times. + * @param isSink Whether the node is a sink. + * @param isSource Whether the node is a source. + */ public ServerNode(String name, int maxServers, Distribution distribution, boolean isSink, boolean isSource) { this.name = name; this.maxServers = maxServers; @@ -30,11 +55,21 @@ public class ServerNode { this.isSource = isSource; } + /** + * Adds a child node with the given probability to select it. + * @param node The child node to add. + * @param probability The probability of the child node. + */ public void addChild(ServerNode node, double probability) { this.children.add(new NodeChild(node, probability)); this.sumProbabilities += probability; } + /** + * Gets a child node based on the given random number generator. + * @param rng The random number generator to use. + * @return The child node selected based on the probabilities. + */ public ServerNode getChild(Rng rng) { var random = rng.random(); for (var child : this.children) { @@ -46,6 +81,9 @@ public class ServerNode { return null; } + /** + * Represents a child node with a probability to select it. + */ public static class NodeChild { public final ServerNode node; public final double probability; diff --git a/src/main/java/net/berack/upo/valpre/rand/Distribution.java b/src/main/java/net/berack/upo/valpre/rand/Distribution.java index 9f6801a..f5cf58c 100644 --- a/src/main/java/net/berack/upo/valpre/rand/Distribution.java +++ b/src/main/java/net/berack/upo/valpre/rand/Distribution.java @@ -1,11 +1,21 @@ package net.berack.upo.valpre.rand; +/** + * Represents a probability distribution. + */ public interface Distribution { public double sample(Rng rng); + /** + * Represents an exponential distribution. + */ public static class Exponential implements Distribution { private final double lambda; + /** + * Creates a new exponential distribution with the given rate. + * @param lambda The rate of the distribution. + */ public Exponential(double lambda) { this.lambda = lambda; } @@ -16,10 +26,18 @@ public interface Distribution { } } + /** + * Represents a normal distribution. + */ public static class Normal implements Distribution { private final double mean; private final double sigma; + /** + * Creates a new normal distribution with the given mean and standard deviation. + * @param mean The mean of the distribution. + * @param sigma The standard deviation of the distribution. + */ public Normal(double mean, double sigma) { this.mean = mean; this.sigma = sigma; @@ -32,11 +50,19 @@ public interface Distribution { } } + /** + * Represents a normal distribution using the Box-Muller transform. + */ public static class NormalBoxMuller implements Distribution { private final double mean; private final double sigma; private double next = Double.NaN; + /** + * Creates a new normal distribution with the given mean and standard deviation. + * @param mean The mean of the distribution. + * @param sigma The standard deviation of the distribution. + */ public NormalBoxMuller(double mean, double sigma) { this.mean = mean; this.sigma = sigma;