summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-flow/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-simulator/opendc-simulator-flow/src/main/java')
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/engine/FlowEngine.java8
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java14
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java23
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowGraph.java115
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowNode.java52
5 files changed, 63 insertions, 149 deletions
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/engine/FlowEngine.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/engine/FlowEngine.java
index 3f18ac76..e5dbb7a8 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/engine/FlowEngine.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/engine/FlowEngine.java
@@ -26,7 +26,6 @@ import java.time.Clock;
import java.time.InstantSource;
import kotlin.coroutines.CoroutineContext;
import org.opendc.common.Dispatcher;
-import org.opendc.simulator.engine.graph.FlowGraph;
import org.opendc.simulator.engine.graph.FlowNode;
/**
@@ -79,13 +78,6 @@ public final class FlowEngine implements Runnable {
}
/**
- * Return a new {@link FlowGraph} that can be used to build a flow network.
- */
- public FlowGraph newGraph() {
- return new FlowGraph(this);
- }
-
- /**
* Enqueue the specified {@link FlowNode} to be updated immediately during the active engine cycle.
* <p>
* This method should be used when the state of a flow context is invalidated/interrupted and needs to be
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java
index c094560e..09cd73f6 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java
@@ -25,8 +25,11 @@ package org.opendc.simulator.engine.graph;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import org.opendc.simulator.engine.engine.FlowEngine;
public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsumer {
private final ArrayList<FlowEdge> consumerEdges = new ArrayList<>();
@@ -45,8 +48,8 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
private double capacity; // What is the max capacity. Can probably be removed
- public FlowDistributor(FlowGraph graph) {
- super(graph);
+ public FlowDistributor(FlowEngine engine) {
+ super(engine);
}
public double getTotalIncomingDemand() {
@@ -283,4 +286,11 @@ public class FlowDistributor extends FlowNode implements FlowSupplier, FlowConsu
outgoingSupplies.set(idx, newSupply);
consumerEdge.pushSupply(newSupply);
}
+
+ @Override
+ public Map<FlowEdge.NodeType, List<FlowEdge>> getConnectedEdges() {
+ List<FlowEdge> supplyingEdges = (this.supplierEdge != null) ? List.of(this.supplierEdge) : List.of();
+
+ return Map.of(FlowEdge.NodeType.CONSUMING, supplyingEdges, FlowEdge.NodeType.SUPPLYING, this.consumerEdges);
+ }
}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java
index 9521f2ce..95eac20b 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowEdge.java
@@ -40,6 +40,11 @@ public class FlowEdge {
private double capacity;
+ public enum NodeType {
+ CONSUMING,
+ SUPPLYING
+ }
+
public FlowEdge(FlowConsumer consumer, FlowSupplier supplier) {
if (!(consumer instanceof FlowNode)) {
throw new IllegalArgumentException("Flow consumer is not a FlowNode");
@@ -69,6 +74,24 @@ public class FlowEdge {
}
}
+ /**
+ * Close the edge of the specified node type.
+ *
+ * @param nodeType The type of connected node that is being closed.
+ */
+ public void close(NodeType nodeType) {
+ if (nodeType == NodeType.CONSUMING) {
+ this.consumer = null;
+ this.supplier.removeConsumerEdge(this);
+ this.supplier = null;
+ }
+ if (nodeType == NodeType.SUPPLYING) {
+ this.supplier = null;
+ this.consumer.removeSupplierEdge(this);
+ this.consumer = null;
+ }
+ }
+
public FlowConsumer getConsumer() {
return consumer;
}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowGraph.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowGraph.java
deleted file mode 100644
index 60d57785..00000000
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowGraph.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2024 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.simulator.engine.graph;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import org.opendc.simulator.engine.engine.FlowEngine;
-
-public class FlowGraph {
- private final FlowEngine engine;
- private final ArrayList<FlowNode> nodes = new ArrayList<>();
- private final ArrayList<FlowEdge> edges = new ArrayList<>();
- private final HashMap<FlowNode, ArrayList<FlowEdge>> nodeToEdge = new HashMap<>();
-
- public FlowGraph(FlowEngine engine) {
- this.engine = engine;
- }
-
- /**
- * Return the {@link FlowEngine} driving the simulation of the graph.
- */
- public FlowEngine getEngine() {
- return engine;
- }
-
- /**
- * Create a new {@link FlowNode} representing a node in the flow network.
- */
- public void addNode(FlowNode node) {
- if (nodes.contains(node)) {
- System.out.println("Node already exists");
- }
- nodes.add(node);
- nodeToEdge.put(node, new ArrayList<>());
- long now = this.engine.getClock().millis();
- node.invalidate(now);
- }
-
- /**
- * Internal method to remove the specified {@link FlowNode} from the graph.
- */
- public void removeNode(FlowNode node) {
-
- // Remove all edges connected to node
- final ArrayList<FlowEdge> connectedEdges = nodeToEdge.get(node);
- while (!connectedEdges.isEmpty()) {
- removeEdge(connectedEdges.get(0));
- }
-
- nodeToEdge.remove(node);
-
- // remove the node
- nodes.remove(node);
- }
-
- /**
- * Add an edge between the specified consumer and supplier in this graph.
- */
- public FlowEdge addEdge(FlowConsumer flowConsumer, FlowSupplier flowSupplier) {
- // Check if the consumer and supplier are both FlowNodes
- if (!(flowConsumer instanceof FlowNode)) {
- throw new IllegalArgumentException("Flow consumer is not a FlowNode");
- }
- if (!(flowSupplier instanceof FlowNode)) {
- throw new IllegalArgumentException("Flow consumer is not a FlowNode");
- }
-
- // Check of the consumer and supplier are present in this graph
- if (!(this.nodes.contains((FlowNode) flowConsumer))) {
- throw new IllegalArgumentException("The consumer is not a node in this graph");
- }
- if (!(this.nodes.contains((FlowNode) flowSupplier))) {
- throw new IllegalArgumentException("The supplier is not a node in this graph");
- }
-
- final FlowEdge flowEdge = new FlowEdge(flowConsumer, flowSupplier);
-
- edges.add(flowEdge);
-
- nodeToEdge.get((FlowNode) flowConsumer).add(flowEdge);
- nodeToEdge.get((FlowNode) flowSupplier).add(flowEdge);
-
- return flowEdge;
- }
-
- public void removeEdge(FlowEdge flowEdge) {
- final FlowConsumer consumer = flowEdge.getConsumer();
- final FlowSupplier supplier = flowEdge.getSupplier();
- nodeToEdge.get((FlowNode) consumer).remove(flowEdge);
- nodeToEdge.get((FlowNode) supplier).remove(flowEdge);
-
- edges.remove(flowEdge);
- flowEdge.close();
- }
-}
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowNode.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowNode.java
index e24e9f93..cbfe39a3 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowNode.java
+++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowNode.java
@@ -23,13 +23,15 @@
package org.opendc.simulator.engine.graph;
import java.time.InstantSource;
+import java.util.List;
+import java.util.Map;
import org.opendc.simulator.engine.engine.FlowEngine;
import org.opendc.simulator.engine.engine.FlowEventQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * A {@link FlowNode} represents a node in a {@link FlowGraph}.
+ * A {@link FlowNode} represents a node in the {@link FlowEngine}.
*/
public abstract class FlowNode {
private static final Logger LOGGER = LoggerFactory.getLogger(FlowNode.class);
@@ -76,14 +78,6 @@ public abstract class FlowNode {
this.clock = clock;
}
- public FlowGraph getParentGraph() {
- return parentGraph;
- }
-
- public void setParentGraph(FlowGraph parentGraph) {
- this.parentGraph = parentGraph;
- }
-
public FlowEngine getEngine() {
return engine;
}
@@ -116,29 +110,22 @@ public abstract class FlowNode {
private Boolean inCycleQueue = false;
protected InstantSource clock;
- protected FlowGraph parentGraph;
protected FlowEngine engine;
/**
- * Return the {@link FlowGraph} to which this stage belongs.
- */
- public FlowGraph getGraph() {
- return parentGraph;
- }
-
- /**
* Construct a new {@link FlowNode} instance.
*
- * @param parentGraph The {@link FlowGraph} this stage belongs to.
+ * @param engine The {@link FlowEngine} driving the simulation.
*/
- public FlowNode(FlowGraph parentGraph) {
- this.parentGraph = parentGraph;
- this.engine = parentGraph.getEngine();
+ public FlowNode(FlowEngine engine) {
+ this.engine = engine;
this.clock = engine.getClock();
- this.parentGraph.addNode(this);
+ this.invalidate();
}
+ public abstract Map<FlowEdge.NodeType, List<FlowEdge>> getConnectedEdges();
+
/**
* Invalidate the {@link FlowNode} forcing the stage to update.
*
@@ -228,8 +215,25 @@ public abstract class FlowNode {
// Mark the stage as closed
this.nodeState = NodeState.CLOSED;
- // Remove stage from parent graph
- this.parentGraph.removeNode(this);
+ // Get Connected Edges
+ Map<FlowEdge.NodeType, List<FlowEdge>> connectedEdges = getConnectedEdges();
+
+ // Remove connected edges
+ List<FlowEdge> consumerEdges = connectedEdges.get(FlowEdge.NodeType.CONSUMING);
+ if (consumerEdges != null) {
+ for (FlowEdge edge : consumerEdges) {
+ edge.close(FlowEdge.NodeType.CONSUMING);
+ }
+ }
+
+ // Remove connected edges
+ List<FlowEdge> supplierEdges = connectedEdges.get(FlowEdge.NodeType.SUPPLYING);
+
+ if (supplierEdges != null) {
+ for (FlowEdge edge : supplierEdges) {
+ edge.close(FlowEdge.NodeType.SUPPLYING);
+ }
+ }
// Remove stage from the timer queue
this.deadline = Long.MAX_VALUE;