diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2025-10-17 16:39:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-17 16:39:50 +0200 |
| commit | 59898b873eabc72719376854770c55e8d8efaa0f (patch) | |
| tree | ddd209df7c680f814ee67098431070dc7e0d6d3a /opendc-simulator/opendc-simulator-flow/src/main/java | |
| parent | 4181a4bd51b54a5905be1f46f74c1349776e35c2 (diff) | |
Updated FlowDistributor to use arrays for suppliers instead of maps (#378)
Diffstat (limited to 'opendc-simulator/opendc-simulator-flow/src/main/java')
7 files changed, 138 insertions, 131 deletions
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 39712f20..137eb44f 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 @@ -58,14 +58,17 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, protected final boolean[] updatedDemands; protected int numUpdatedDemands = 0; - // protected ArrayList<Integer> updatedDemands = new ArrayList<>(); protected double previousTotalDemand = 0.0; protected double totalIncomingDemand; // The total demand of all the consumers - protected HashMap<Integer, FlowEdge> supplierEdges = new HashMap<>(); - protected HashMap<Integer, Double> currentIncomingSupplies = - new HashMap<>(); // The current supply provided by the suppliers + protected final ArrayList<Integer> availableSupplierIndices; + protected final ArrayList<Integer> usedSupplierIndices; + + protected int numSuppliers = 0; + protected final int maxSuppliers; + protected final FlowEdge[] supplierEdges; + protected final double[] incomingSupplies; protected Double totalIncomingSupply = 0.0; // The total supply provided by the suppliers protected boolean outgoingDemandUpdateNeeded = false; @@ -80,10 +83,11 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, protected boolean overloaded = false; - public FlowDistributor(FlowEngine engine, int maxConsumers) { + public FlowDistributor(FlowEngine engine, int maxConsumers, int maxSuppliers) { super(engine); this.maxConsumers = maxConsumers; + this.maxSuppliers = 4; this.availableConsumerIndices = new ArrayList<>(this.maxConsumers); this.usedConsumerIndices = new ArrayList<>(this.maxConsumers); @@ -92,10 +96,17 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, this.availableConsumerIndices.add(i); } + this.availableSupplierIndices = new ArrayList<>(this.maxSuppliers); + this.usedSupplierIndices = new ArrayList<>(this.maxSuppliers); + + for (int i = 0; i < this.maxSuppliers; i++) { + this.availableSupplierIndices.add(i); + } + this.consumerEdges = new FlowEdge[this.maxConsumers]; - // this.supplierEdges = new FlowEdge[this.maxSuppliers]; - // this.incomingSupplies = new double[this.maxSuppliers]; + this.supplierEdges = new FlowEdge[this.maxSuppliers]; + this.incomingSupplies = new double[this.maxSuppliers]; this.incomingDemands = new double[this.maxConsumers]; this.outgoingSupplies = new double[this.maxConsumers]; @@ -135,7 +146,7 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, protected abstract void updateOutgoingSupplies(); - public abstract double[] distributeSupply(double[] demands, ArrayList<Double> currentSupply, double totalSupply); + public abstract double[] distributeSupply(double[] demands, double[] currentSupply, double totalSupply); /** * Add a new consumer. @@ -154,12 +165,15 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, @Override public void addSupplierEdge(FlowEdge supplierEdge) { - // supplierIndex not always set, so we use 0 as default to avoid index out of bounds - int supplierIndex = supplierEdge.getSupplierIndex() == -1 ? 0 : supplierEdge.getSupplierIndex(); + int supplierIndex = this.availableSupplierIndices.removeFirst(); + this.usedSupplierIndices.add(supplierIndex); + + supplierEdge.setSupplierIndex(supplierIndex); + this.supplierEdges[supplierIndex] = supplierEdge; + + this.numSuppliers++; - this.supplierEdges.put(supplierIndex, supplierEdge); this.capacity += supplierEdge.getCapacity(); - this.currentIncomingSupplies.put(supplierIndex, 0.0); this.supplierResourceType = supplierEdge.getSupplierResourceType(); } @@ -176,11 +190,6 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, this.totalIncomingDemand = 0.0; } - // Remove idx from consumers that updated their demands - // if (this.updatedDemands.contains(consumerIndex)) { - // this.updatedDemands.remove(Integer.valueOf(consumerIndex)); - // } - this.updatedDemands[consumerIndex] = false; this.consumerEdges[consumerIndex] = null; @@ -198,18 +207,24 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, @Override public void removeSupplierEdge(FlowEdge supplierEdge) { - // supplierIndex not always set, so we use 0 as default to avoid index out of bounds - int idx = supplierEdge.getSupplierIndex() == -1 ? 0 : supplierEdge.getSupplierIndex(); + int supplierIndex = supplierEdge.getSupplierIndex(); + + if (supplierIndex == -1) { + return; + } - this.supplierEdges.remove(idx); this.capacity -= supplierEdge.getCapacity(); - this.currentIncomingSupplies.put(idx, 0.0); - if (this.supplierEdges.isEmpty()) { - // this.updatedDemands.clear(); - Arrays.fill(this.updatedDemands, false); - this.numUpdatedDemands = 0; - } + this.supplierEdges[supplierIndex] = null; + this.incomingSupplies[supplierIndex] = 0.0; + + this.usedSupplierIndices.remove(Integer.valueOf(supplierIndex)); + this.availableSupplierIndices.add(supplierIndex); + + this.numSuppliers--; + + this.outgoingDemandUpdateNeeded = true; + this.invalidate(); } @Override @@ -231,8 +246,6 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, this.totalIncomingDemand = 0.0; } - // TODO: can be optimized by using a boolean array - // this.updatedDemands.add(consumerIndex); this.updatedDemands[consumerIndex] = true; this.numUpdatedDemands++; @@ -252,12 +265,16 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, @Override public void handleIncomingSupply(FlowEdge supplierEdge, double newSupply) { - // supplierIndex not always set, so we use 0 as default to avoid index out of bounds - int idx = supplierEdge.getSupplierIndex() == -1 ? 0 : supplierEdge.getSupplierIndex(); - double prevSupply = currentIncomingSupplies.get(idx); + int supplierIndex = supplierEdge.getSupplierIndex(); - currentIncomingSupplies.put(idx, newSupply); - // only update the total supply if the new supply is different from the previous one + if (supplierIndex == -1) { + LOGGER.warn("Demand {} pushed by an unknown supplier", newSupply); + return; + } + + double prevSupply = incomingSupplies[supplierIndex]; + + incomingSupplies[supplierIndex] = newSupply; this.totalIncomingSupply += (newSupply - prevSupply); this.outgoingSupplyUpdateNeeded = true; @@ -292,7 +309,7 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, FlowEdge.NodeType.CONSUMING, Arrays.asList(this.consumerEdges), FlowEdge.NodeType.SUPPLYING, - new ArrayList<>(this.supplierEdges.values())); + Arrays.asList(this.supplierEdges)); } @Override @@ -306,7 +323,7 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, } public Boolean hasSupplierEdges() { - for (FlowEdge edge : this.supplierEdges.values()) { + for (FlowEdge edge : this.supplierEdges) { if (edge != null) { return true; } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java index 5446f261..eec1d90e 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java @@ -47,8 +47,9 @@ public class BestEffortFlowDistributor extends FlowDistributor { private final long roundRobinInterval; private long lastRoundRobinUpdate; - public BestEffortFlowDistributor(FlowEngine flowEngine, long roundRobinInterval, int maxConsumers) { - super(flowEngine, maxConsumers); + public BestEffortFlowDistributor( + FlowEngine flowEngine, long roundRobinInterval, int maxConsumers, int maxSuppliers) { + super(flowEngine, maxConsumers, maxSuppliers); this.roundRobinInterval = roundRobinInterval; this.lastRoundRobinUpdate = -roundRobinInterval; } @@ -66,10 +67,9 @@ public class BestEffortFlowDistributor extends FlowDistributor { double remainingDemand = this.totalIncomingDemand; // Phase 1: Prioritize suppliers that are currently providing supply - for (var entry : this.supplierEdges.entrySet()) { - int supplierIdx = entry.getKey(); - FlowEdge supplierEdge = entry.getValue(); - double currentSupply = this.currentIncomingSupplies.get(supplierIdx); + for (int supplierIndex : this.usedSupplierIndices) { + FlowEdge supplierEdge = this.supplierEdges[supplierIndex]; + double currentSupply = this.incomingSupplies[supplierIndex]; if (currentSupply > 0 && remainingDemand > 0) { // Try to satisfy as much demand as possible from this already active supplier @@ -81,10 +81,9 @@ public class BestEffortFlowDistributor extends FlowDistributor { // Phase 2: If demand still remains, use inactive suppliers if (remainingDemand > 0) { - for (var entry : this.supplierEdges.entrySet()) { - int supplierIdx = entry.getKey(); - FlowEdge supplierEdge = entry.getValue(); - double currentSupply = this.currentIncomingSupplies.get(supplierIdx); + for (int supplierIndex : this.usedSupplierIndices) { + FlowEdge supplierEdge = this.supplierEdges[supplierIndex]; + double currentSupply = this.incomingSupplies[supplierIndex]; if (currentSupply == 0 && remainingDemand > 0) { double demandForThisSupplier = Math.min(remainingDemand, supplierEdge.getCapacity()); @@ -95,10 +94,10 @@ public class BestEffortFlowDistributor extends FlowDistributor { } } else { // System is overloaded or no demand: distribute demand equally across all suppliers - double demandPerSupplier = this.totalIncomingDemand / this.supplierEdges.size(); + double demandPerSupplier = this.totalIncomingDemand / this.numSuppliers; - for (FlowEdge supplierEdge : this.supplierEdges.values()) { - this.pushOutgoingDemand(supplierEdge, demandPerSupplier); + for (int supplierIndex : this.usedSupplierIndices) { + this.pushOutgoingDemand(this.supplierEdges[supplierIndex], demandPerSupplier); } } @@ -117,10 +116,8 @@ public class BestEffortFlowDistributor extends FlowDistributor { this.overloaded = true; // Use the distribution algorithm for supply allocation - double[] supplies = this.distributeSupply( - this.incomingDemands, - new ArrayList<>(this.currentIncomingSupplies.values()), - this.totalIncomingSupply); + double[] supplies = + this.distributeSupply(this.incomingDemands, this.incomingSupplies, this.totalIncomingSupply); for (int consumerIndex : this.usedConsumerIndices) { this.pushOutgoingSupply( @@ -153,18 +150,10 @@ public class BestEffortFlowDistributor extends FlowDistributor { this.incomingDemands[consumerIndex], this.getConsumerResourceType()); } - - // for (int consumerIndex : this.updatedDemands) { - // this.pushOutgoingSupply( - // this.consumerEdges[consumerIndex], - // this.incomingDemands[consumerIndex], - // this.getConsumerResourceType()); - // } } } this.outgoingSupplyUpdateNeeded = false; - // this.updatedDemands.clear(); Arrays.fill(this.updatedDemands, false); this.numUpdatedDemands = 0; } @@ -177,7 +166,7 @@ public class BestEffortFlowDistributor extends FlowDistributor { * 3. Optimize utilization by giving extra capacity to active consumers */ @Override - public double[] distributeSupply(double[] demands, ArrayList<Double> currentSupply, double totalSupply) { + public double[] distributeSupply(double[] demands, double[] currentSupply, double totalSupply) { int numConsumers = this.consumerEdges.length; double[] allocation = new double[numConsumers]; diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java index 6938f7d7..92a3905b 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java @@ -22,7 +22,6 @@ package org.opendc.simulator.engine.graph.distributionPolicies; -import java.util.ArrayList; import java.util.Arrays; import org.opendc.simulator.engine.engine.FlowEngine; import org.opendc.simulator.engine.graph.FlowDistributor; @@ -36,8 +35,8 @@ import org.opendc.simulator.engine.graph.FlowDistributor; */ public class EqualShareFlowDistributor extends FlowDistributor { - public EqualShareFlowDistributor(FlowEngine engine, int maxConsumers) { - super(engine, maxConsumers); + public EqualShareFlowDistributor(FlowEngine engine, int maxConsumers, int maxSuppliers) { + super(engine, maxConsumers, maxSuppliers); } /** @@ -47,10 +46,10 @@ public class EqualShareFlowDistributor extends FlowDistributor { */ @Override protected void updateOutgoingDemand() { - double equalShare = this.capacity / this.supplierEdges.size(); + double equalShare = this.capacity / this.numSuppliers; - for (var supplierEdge : this.supplierEdges.values()) { - this.pushOutgoingDemand(supplierEdge, equalShare); + for (int supplierIndex : this.usedSupplierIndices) { + this.pushOutgoingDemand(this.supplierEdges[supplierIndex], equalShare); } this.outgoingDemandUpdateNeeded = false; @@ -63,8 +62,7 @@ public class EqualShareFlowDistributor extends FlowDistributor { */ @Override protected void updateOutgoingSupplies() { - double[] equalShare = distributeSupply( - incomingDemands, new ArrayList<>(this.currentIncomingSupplies.values()), this.capacity); + double[] equalShare = distributeSupply(incomingDemands, this.incomingSupplies, this.capacity); for (int consumerIndex : this.usedConsumerIndices) { this.pushOutgoingSupply( @@ -76,7 +74,7 @@ public class EqualShareFlowDistributor extends FlowDistributor { } @Override - public double[] distributeSupply(double[] demands, ArrayList<Double> currentSupply, double totalSupply) { + public double[] distributeSupply(double[] demands, double[] currentSupply, double totalSupply) { double[] allocation = new double[this.numConsumers]; double equalShare = totalSupply / this.numConsumers; diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java index 67458ad6..41f0a2d3 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java @@ -22,9 +22,9 @@ package org.opendc.simulator.engine.graph.distributionPolicies; -import java.util.ArrayList; import org.opendc.simulator.engine.engine.FlowEngine; import org.opendc.simulator.engine.graph.FlowDistributor; +import org.opendc.simulator.engine.graph.FlowEdge; /** * A {@link FlowDistributor} that implements the First Fit policy for distributing flow. @@ -36,8 +36,8 @@ import org.opendc.simulator.engine.graph.FlowDistributor; */ public class FirstFitPolicyFlowDistributor extends FlowDistributor { - public FirstFitPolicyFlowDistributor(FlowEngine engine, int maxConsumers) { - super(engine, maxConsumers); + public FirstFitPolicyFlowDistributor(FlowEngine engine, int maxConsumers, int maxSuppliers) { + super(engine, maxConsumers, maxSuppliers); } /** @@ -48,14 +48,9 @@ public class FirstFitPolicyFlowDistributor extends FlowDistributor { protected void updateOutgoingDemand() { double remainingDemand = this.totalIncomingDemand; - // Sort supplier edges by their index to ensure consistent first-fit ordering - var sortedSuppliers = this.supplierEdges.entrySet().stream() - .sorted((e1, e2) -> Integer.compare(e1.getKey(), e2.getKey())) - .toList(); - // Apply First Fit strategy: fill suppliers in order until demand is satisfied - for (var supplierEntry : sortedSuppliers) { - var supplierEdge = supplierEntry.getValue(); + for (int supplierIndex : this.usedSupplierIndices) { + FlowEdge supplierEdge = this.supplierEdges[supplierIndex]; double supplierCapacity = supplierEdge.getCapacity(); if (remainingDemand <= 0) { @@ -82,12 +77,17 @@ public class FirstFitPolicyFlowDistributor extends FlowDistributor { */ @Override protected void updateOutgoingSupplies() { - ArrayList<Double> currentPossibleSupplies = new ArrayList<>(); - for (var currentIncomingSupply : currentIncomingSupplies.entrySet()) { - currentPossibleSupplies.add(currentIncomingSupply.getValue()); - } - - double[] shares = distributeSupply(incomingDemands, currentPossibleSupplies, totalIncomingSupply); + // ArrayList<Double> currentPossibleSupplies = new ArrayList<>(); + // + // + // + // + // for (var currentIncomingSupply : incomingSupplies.entrySet()) { + // currentPossibleSupplies.add(currentIncomingSupply.getValue()); + // } + + // double[] shares = distributeSupply(incomingDemands, currentPossibleSupplies, totalIncomingSupply); + double[] shares = distributeSupply(this.incomingDemands, this.incomingSupplies, this.totalIncomingSupply); for (int consumerIndex : this.usedConsumerIndices) { this.pushOutgoingSupply( @@ -108,22 +108,24 @@ public class FirstFitPolicyFlowDistributor extends FlowDistributor { * @see #updateOutgoingSupplies() */ @Override - public double[] distributeSupply(double[] demands, ArrayList<Double> currentSupply, double totalSupply) { - int numConsumers = demands.length; - double[] allocation = new double[numConsumers]; + public double[] distributeSupply(double[] demands, double[] currentSupply, double totalSupply) { + double[] allocation = new double[this.numConsumers]; // Create a copy of current supply to track remaining capacity as we allocate - ArrayList<Double> remainingSupply = new ArrayList<>(currentSupply); + double[] remainingSupply = new double[currentSupply.length]; + System.arraycopy(currentSupply, 0, remainingSupply, 0, currentSupply.length); // For each demand, try to satisfy it using suppliers in order - for (int i = 0; i < numConsumers; i++) { - double remainingDemand = demands[i]; + for (int consumerIndex : this.usedConsumerIndices) { + double remainingDemand = demands[consumerIndex]; double totalAllocated = 0.0; if (remainingDemand > 0) { // Try each supplier in order until demand is satisfied - for (int j = 0; j < remainingSupply.size() && remainingDemand > 0; j++) { - double availableSupply = remainingSupply.get(j); + for (int supplierIndex = 0; + supplierIndex < remainingSupply.length && remainingDemand > 0; + supplierIndex++) { + double availableSupply = remainingSupply[supplierIndex]; if (availableSupply > 0) { // Allocate as much as possible from this supplier @@ -133,12 +135,12 @@ public class FirstFitPolicyFlowDistributor extends FlowDistributor { remainingDemand -= allocatedFromThisSupplier; // Reduce the remaining supply capacity - remainingSupply.set(j, availableSupply - allocatedFromThisSupplier); + remainingSupply[supplierIndex] = availableSupply - allocatedFromThisSupplier; } } } - allocation[i] = totalAllocated; + allocation[consumerIndex] = totalAllocated; } return allocation; diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java index 7a586b72..048af86e 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java @@ -57,8 +57,8 @@ public class FixedShareFlowDistributor extends FlowDistributor { * @param engine The flow engine * @param shareRatio The fixed share ratio for each consumer (between 0.0 and 1.0) */ - public FixedShareFlowDistributor(FlowEngine engine, double shareRatio, int maxConsumers) { - super(engine, maxConsumers); + public FixedShareFlowDistributor(FlowEngine engine, double shareRatio, int maxConsumers, int maxSuppliers) { + super(engine, maxConsumers, maxSuppliers); if (shareRatio <= 0 || shareRatio > 1) { throw new IllegalArgumentException("Share ratio must be between 0.0 and 1.0"); @@ -66,7 +66,7 @@ public class FixedShareFlowDistributor extends FlowDistributor { this.shareRatio = shareRatio; // Each consumer gets an equal fixed share of the total capacity - this.fixedShare = this.shareRatio * this.capacity / this.supplierEdges.size(); + this.fixedShare = this.shareRatio * this.capacity / this.numSuppliers; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -80,10 +80,13 @@ public class FixedShareFlowDistributor extends FlowDistributor { @Override protected void updateOutgoingDemand() { // Calculate total demand based on active consumers - this.fixedShare = this.shareRatio * this.capacity / this.supplierEdges.size(); + this.fixedShare = this.shareRatio * this.capacity / this.numSuppliers; // Distribute demand equally across all suppliers - for (FlowEdge supplierEdge : supplierEdges.values()) { + for (FlowEdge supplierEdge : this.supplierEdges) { + if (supplierEdge == null) { + continue; + } this.pushOutgoingDemand(supplierEdge, this.fixedShare); } @@ -99,8 +102,7 @@ public class FixedShareFlowDistributor extends FlowDistributor { protected void updateOutgoingSupplies() { // Calculate the fixed allocation per consumer - double[] supplies = distributeSupply( - this.incomingDemands, new ArrayList<>(this.currentIncomingSupplies.values()), this.totalIncomingSupply); + double[] supplies = distributeSupply(this.incomingDemands, this.incomingSupplies, this.totalIncomingSupply); for (int consumerIndex : this.usedConsumerIndices) { this.pushOutgoingSupply( @@ -108,10 +110,10 @@ public class FixedShareFlowDistributor extends FlowDistributor { } } - public double[] distributeSupply(double[] demands, ArrayList<Double> currentSupply, double totalSupply) { + public double[] distributeSupply(double[] demands, double[] currentSupply, double totalSupply) { double[] supplies = new double[this.maxConsumers]; - if (this.numConsumers < this.supplierEdges.size() && this.fixedShare * this.numConsumers <= totalSupply) { + if (this.numConsumers < this.supplierEdges.length && this.fixedShare * this.numConsumers <= totalSupply) { for (int consumerIndex : this.usedConsumerIndices) { supplies[consumerIndex] = this.fixedShare; diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FlowDistributorFactory.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FlowDistributorFactory.java index 96e42d4c..d3d5fa56 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FlowDistributorFactory.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FlowDistributorFactory.java @@ -57,22 +57,28 @@ public class FlowDistributorFactory { } public static FlowDistributor getFlowDistributor( - FlowEngine flowEngine, DistributionPolicy distributionPolicyType, int maxConsumers) { + FlowEngine flowEngine, DistributionPolicy distributionPolicyType, int maxConsumers, int maxSuppliers) { return switch (distributionPolicyType) { case BEST_EFFORT -> new BestEffortFlowDistributor( - flowEngine, distributionPolicyType.getProperty("updateIntervalLength", Long.class), maxConsumers); - case EQUAL_SHARE -> new EqualShareFlowDistributor(flowEngine, maxConsumers); - case FIRST_FIT -> new FirstFitPolicyFlowDistributor(flowEngine, maxConsumers); + flowEngine, + distributionPolicyType.getProperty("updateIntervalLength", Long.class), + maxConsumers, + maxSuppliers); + case EQUAL_SHARE -> new EqualShareFlowDistributor(flowEngine, maxConsumers, maxSuppliers); + case FIRST_FIT -> new FirstFitPolicyFlowDistributor(flowEngine, maxConsumers, maxSuppliers); case FIXED_SHARE -> { if (!distributionPolicyType.getPropertyNames().contains("shareRatio")) { throw new IllegalArgumentException( "FixedShare distribution policy requires a 'shareRatio' property to be set."); } yield new FixedShareFlowDistributor( - flowEngine, distributionPolicyType.getProperty("shareRatio", Double.class), maxConsumers); + flowEngine, + distributionPolicyType.getProperty("shareRatio", Double.class), + maxConsumers, + maxSuppliers); } - default -> new MaxMinFairnessFlowDistributor(flowEngine, maxConsumers); + default -> new MaxMinFairnessFlowDistributor(flowEngine, maxConsumers, maxSuppliers); }; } } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessFlowDistributor.java index b8337b7a..2133930c 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessFlowDistributor.java @@ -22,11 +22,9 @@ package org.opendc.simulator.engine.graph.distributionPolicies; -import java.util.ArrayList; import java.util.Arrays; import org.opendc.simulator.engine.engine.FlowEngine; import org.opendc.simulator.engine.graph.FlowDistributor; -import org.opendc.simulator.engine.graph.FlowEdge; /** * A flow distributor that implements the max-min fairness distribution policy. @@ -36,8 +34,8 @@ import org.opendc.simulator.engine.graph.FlowEdge; */ public class MaxMinFairnessFlowDistributor extends FlowDistributor { - public MaxMinFairnessFlowDistributor(FlowEngine engine, int maxConsumers) { - super(engine, maxConsumers); + public MaxMinFairnessFlowDistributor(FlowEngine engine, int maxConsumers, int maxSuppliers) { + super(engine, maxConsumers, maxSuppliers); } protected void updateOutgoingDemand() { @@ -49,10 +47,16 @@ public class MaxMinFairnessFlowDistributor extends FlowDistributor { this.previousTotalDemand = this.totalIncomingDemand; - for (FlowEdge supplierEdge : this.supplierEdges.values()) { - this.pushOutgoingDemand(supplierEdge, this.totalIncomingDemand / this.supplierEdges.size()); + double demandPerSupplier = this.totalIncomingDemand / this.numSuppliers; + + for (int supplierIndex : this.usedSupplierIndices) { + this.pushOutgoingDemand(this.supplierEdges[supplierIndex], demandPerSupplier); } + // for (FlowEdge supplierEdge : this.supplierEdges.values()) { + // this.pushOutgoingDemand(supplierEdge, this.totalIncomingDemand / this.numSuppliers); + // } + this.outgoingDemandUpdateNeeded = false; } @@ -65,10 +69,8 @@ public class MaxMinFairnessFlowDistributor extends FlowDistributor { if (this.totalIncomingDemand > this.totalIncomingSupply) { this.overloaded = true; - double[] supplies = this.distributeSupply( - this.incomingDemands, - new ArrayList<>(this.currentIncomingSupplies.values()), - this.totalIncomingSupply); + double[] supplies = + this.distributeSupply(this.incomingDemands, this.incomingSupplies, this.totalIncomingSupply); for (int consumerIndex : this.usedConsumerIndices) { this.pushOutgoingSupply( @@ -103,25 +105,16 @@ public class MaxMinFairnessFlowDistributor extends FlowDistributor { this.incomingDemands[consumerIndex], this.getConsumerResourceType()); } - - // - // for (int consumerIndex : this.updatedDemands) { - // this.pushOutgoingSupply( - // this.consumerEdges[consumerIndex], - // this.incomingDemands[consumerIndex], - // this.getConsumerResourceType()); - // } } } - // this.updatedDemands.clear(); Arrays.fill(this.updatedDemands, false); this.numUpdatedDemands = 0; } private record Demand(int idx, double value) {} - public double[] distributeSupply(double[] demands, ArrayList<Double> currentSupply, double totalSupply) { + public double[] distributeSupply(double[] demands, double[] currentSupply, double totalSupply) { int inputSize = demands.length; final double[] supplies = new double[inputSize]; |
