Refactor simulation and net example tests to use builder pattern for ServerNode and improve arrival handling logic
This commit is contained in:
@@ -74,12 +74,12 @@ public class NetBuilderInteractive {
|
||||
var limit = ask("Arrivals limit (0 for Int.Max): ", Integer::parseInt, 1);
|
||||
if (limit <= 0)
|
||||
limit = Integer.MAX_VALUE;
|
||||
yield ServerNode.createLimitedSource(name, distribution, limit);
|
||||
yield ServerNode.Builder.sourceLimited(name, limit, distribution);
|
||||
}
|
||||
case 2 -> {
|
||||
var servers = ask("Number of servers: ", Integer::parseInt, 1);
|
||||
var unavailable = askDistribution("Unavailable distribution");
|
||||
yield ServerNode.createQueue(name, servers, distribution, unavailable);
|
||||
yield ServerNode.Builder.queue(name, servers, distribution, unavailable);
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
|
||||
@@ -15,84 +15,36 @@ public class ServerNode {
|
||||
public final Distribution service;
|
||||
public final Distribution unavailable;
|
||||
|
||||
/**
|
||||
* Creates a source node with the given name and distribution.
|
||||
* It swpawns infinite arrivals (Integer.MAX_VALUE) that are served by infinite
|
||||
* servers (Integer.MAX_VALUE).
|
||||
*
|
||||
* @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, null, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a source node with the given name, distribution, and number of
|
||||
* arrivals to spawn that are served by infinite servers (Integer.MAX_VALUE).
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param service The distribution of the inter-arrival times.
|
||||
* @param spawnArrivals The number of arrivals to spawn.
|
||||
* @return The created source node.
|
||||
*/
|
||||
public static ServerNode createLimitedSource(String name, Distribution service, int spawnArrivals) {
|
||||
return new ServerNode(name, Integer.MAX_VALUE, service, null, spawnArrivals);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 service The distribution of the service times.
|
||||
* @return The created queue node.
|
||||
*/
|
||||
public static ServerNode createQueue(String name, int maxServers, Distribution service) {
|
||||
return new ServerNode(name, maxServers, service, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 service The distribution of the service times.
|
||||
* @param unavailable The distribution of the unavailable times after service.
|
||||
* @return The created queue node.
|
||||
*/
|
||||
public static ServerNode createQueue(String name, int maxServers, Distribution service, Distribution unavailable) {
|
||||
return new ServerNode(name, maxServers, service, unavailable, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a generic node with the given name and distribution.
|
||||
* The servers number must be 1 or higher; if lower will be put to 1.
|
||||
* The spawn number must be 0 or higher; if lower will be put to 0.
|
||||
* The distribution can't be null, otherwise an exception is thrown.
|
||||
* The queue number must be equal or higher than the servers number; if lower
|
||||
* will be put to the servers number.
|
||||
* The service distribution can't be null, otherwise an exception is thrown.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param maxServers The maximum number of servers in the queue.
|
||||
* @param service The distribution of the service times.
|
||||
* @param unavailable The distribution of the unavailable times after service.
|
||||
* @param spawnArrivals The number of arrivals to spawn.
|
||||
* @param name The name of the node.
|
||||
* @param servers The maximum number of servers in the queue.
|
||||
* @param spawn The number of arrivals to spawn.
|
||||
* @param queue The maximum number of requests in the queue.
|
||||
* @param service The distribution of the service times.
|
||||
* @param unavailable The distribution of the unavailable times after service.
|
||||
* @throws NullPointerException if the distribution is null
|
||||
*/
|
||||
private ServerNode(String name, int maxServers, Distribution service, Distribution unavailable, int spawnArrivals) {
|
||||
private ServerNode(String name, int servers, int spawn, int queue, Distribution service, Distribution unavailable) {
|
||||
if (service == null)
|
||||
throw new NullPointerException("Service distribution can't be null");
|
||||
if (maxServers <= 0)
|
||||
maxServers = 1;
|
||||
if (spawnArrivals < 0)
|
||||
spawnArrivals = 0;
|
||||
if (servers <= 0)
|
||||
servers = 1;
|
||||
if (spawn < 0)
|
||||
spawn = 0;
|
||||
if (queue < servers)
|
||||
queue = servers;
|
||||
|
||||
this.name = name;
|
||||
this.maxQueue = 100; // TODO change to runtime
|
||||
this.maxServers = maxServers;
|
||||
this.spawnArrivals = spawnArrivals;
|
||||
this.maxQueue = queue;
|
||||
this.maxServers = servers;
|
||||
this.spawnArrivals = spawn;
|
||||
this.service = service;
|
||||
this.unavailable = unavailable;
|
||||
}
|
||||
@@ -131,4 +83,114 @@ public class ServerNode {
|
||||
public int hashCode() {
|
||||
return this.name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new builder for the node.
|
||||
* It is useful to create a node with a more readable syntax and a in a more
|
||||
* flexible way.
|
||||
*/
|
||||
public static class Builder {
|
||||
private String name;
|
||||
private int maxQueue;
|
||||
private int maxServers;
|
||||
private int spawnArrivals;
|
||||
private Distribution service;
|
||||
private Distribution unavailable;
|
||||
|
||||
/**
|
||||
* Creates a new builder for the node with the given name and distribution.
|
||||
* The maximum number of servers is set to 1, the maximum number of requests in
|
||||
* the queue is set to 100, the number of arrivals to spawn is set to 0, and
|
||||
* the unavailable time is set to null.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param service The distribution of the service times.
|
||||
* @return The created sink node.
|
||||
*/
|
||||
public Builder(String name, Distribution service) {
|
||||
this.name = name;
|
||||
this.service = service;
|
||||
this.maxQueue = 100; // default value
|
||||
this.maxServers = 1;
|
||||
this.spawnArrivals = 0;
|
||||
this.unavailable = null;
|
||||
}
|
||||
|
||||
public Builder queue(int maxQueue) {
|
||||
this.maxQueue = maxQueue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder servers(int maxServers) {
|
||||
this.maxServers = maxServers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder spawn(int spawnArrivals) {
|
||||
this.spawnArrivals = spawnArrivals;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder unavailable(Distribution unavailable) {
|
||||
this.unavailable = unavailable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerNode build() {
|
||||
return new ServerNode(name, maxServers, spawnArrivals, maxQueue, service, unavailable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a source node with the given name and distribution.
|
||||
* It swpawns infinite arrivals (Integer.MAX_VALUE) that are served by infinite
|
||||
* servers (Integer.MAX_VALUE).
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param distribution The distribution of the inter-arrival times.
|
||||
* @return The created source node.
|
||||
*/
|
||||
public static ServerNode source(String name, Distribution distribution) {
|
||||
return new Builder(name, distribution).spawn(Integer.MAX_VALUE).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a source node with the given name, distribution, and number of
|
||||
* arrivals to spawn that are served by infinite servers (Integer.MAX_VALUE).
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param service The distribution of the inter-arrival times.
|
||||
* @param spawnArrivals The number of arrivals to spawn.
|
||||
* @return The created source node.
|
||||
*/
|
||||
public static ServerNode sourceLimited(String name, int spawnArrivals, Distribution service) {
|
||||
return new Builder(name, service).spawn(spawnArrivals).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 service The distribution of the service times.
|
||||
* @return The created queue node.
|
||||
*/
|
||||
public static ServerNode queue(String name, int maxServers, Distribution service) {
|
||||
return new Builder(name, service).servers(maxServers).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 service The distribution of the service times.
|
||||
* @param unavailable The distribution of the unavailable times after service.
|
||||
* @return The created queue node.
|
||||
*/
|
||||
public static ServerNode queue(String name, int maxServers, Distribution service, Distribution unavailable) {
|
||||
return new Builder(name, service).unavailable(unavailable).servers(maxServers).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,8 +97,12 @@ public final class Simulation {
|
||||
|
||||
this.addToFel(state.spawnUnavailableIfPossible(time, this.rng));
|
||||
this.addToFel(state.spawnDepartureIfPossible(time, this.rng));
|
||||
this.addToFel(state.spawnArrivalToChild(time, this.rng));
|
||||
this.addToFel(state.spawnArrivalIfPossilbe(time));
|
||||
|
||||
// Spawn arrival to child node if queue is not full otherwise drop
|
||||
var ev = state.spawnArrivalToChild(time, this.rng);
|
||||
if (ev != null && !this.states[ev.nodeIndex].isQueueFull())
|
||||
this.addToFel(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user