summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-flow
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2025-10-17 16:39:50 +0200
committerGitHub <noreply@github.com>2025-10-17 16:39:50 +0200
commit59898b873eabc72719376854770c55e8d8efaa0f (patch)
treeddd209df7c680f814ee67098431070dc7e0d6d3a /opendc-simulator/opendc-simulator-flow
parent4181a4bd51b54a5905be1f46f74c1349776e35c2 (diff)
Updated FlowDistributor to use arrays for suppliers instead of maps (#378)
Diffstat (limited to 'opendc-simulator/opendc-simulator-flow')
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java87
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java41
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java16
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java54
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java20
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FlowDistributorFactory.java18
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/MaxMinFairnessFlowDistributor.java33
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];