diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2025-03-18 07:26:35 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-18 07:26:35 +0100 |
| commit | 97db8e0351b9451ece8fd16c25ca0588ec71a2ab (patch) | |
| tree | e72f32df2b12677e9ae2f9997b226c8da97e56e4 /opendc-simulator/opendc-simulator-flow/src/main | |
| parent | 7dc2639a7fcdf51ef789f4af2e3afff11438be6e (diff) | |
Performance updates (#314)
Diffstat (limited to 'opendc-simulator/opendc-simulator-flow/src/main')
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; |
