1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

Merge pull request #3473 from qwertyuioplkjhgfd/better-round-robin

Improve Round-Robin Accuracy
This commit is contained in:
TheBusyBiscuit 2022-07-10 13:20:00 +02:00 committed by GitHub
commit 42aed25059
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -151,15 +151,19 @@ class CargoNetworkTask implements Runnable {
boolean roundrobin = Objects.equals(cfg.getString("round-robin"), "true"); boolean roundrobin = Objects.equals(cfg.getString("round-robin"), "true");
boolean smartFill = Objects.equals(cfg.getString("smart-fill"), "true"); boolean smartFill = Objects.equals(cfg.getString("smart-fill"), "true");
int index = 0;
Collection<Location> destinations; Collection<Location> destinations;
if (roundrobin) { if (roundrobin) {
// The current round-robin index of the (unsorted) outputNodes list,
// or the index at which to start searching for valid output nodes
index = network.roundRobin.getOrDefault(inputNode, 0);
// Use an ArrayDeque to perform round-robin sorting // Use an ArrayDeque to perform round-robin sorting
// Since the impl for roundRobinSort just does Deque.addLast(Deque#removeFirst) // Since the impl for roundRobinSort just does Deque.addLast(Deque#removeFirst)
// An ArrayDequeue is preferable as opposed to a LinkedList: // An ArrayDequeue is preferable as opposed to a LinkedList:
// - The number of elements does not change. // - The number of elements does not change.
// - ArrayDequeue has better iterative performance // - ArrayDequeue has better iterative performance
Deque<Location> tempDestinations = new ArrayDeque<>(outputNodes); Deque<Location> tempDestinations = new ArrayDeque<>(outputNodes);
roundRobinSort(inputNode, tempDestinations); roundRobinSort(index, tempDestinations);
destinations = tempDestinations; destinations = tempDestinations;
} else { } else {
// Using an ArrayList here since we won't need to sort the destinations // Using an ArrayList here since we won't need to sort the destinations
@ -175,9 +179,14 @@ class CargoNetworkTask implements Runnable {
item = CargoUtils.insert(network, inventories, output.getBlock(), target.get(), smartFill, item, wrapper); item = CargoUtils.insert(network, inventories, output.getBlock(), target.get(), smartFill, item, wrapper);
if (item == null) { if (item == null) {
if (roundrobin) {
// The output was valid, set the round robin index to the node after this one
network.roundRobin.put(inputNode, (index + 1) % outputNodes.size());
}
break; break;
} }
} }
index++;
} }
return item; return item;
@ -187,27 +196,19 @@ class CargoNetworkTask implements Runnable {
* This method sorts a given {@link Deque} of output node locations using a semi-accurate * This method sorts a given {@link Deque} of output node locations using a semi-accurate
* round-robin method. * round-robin method.
* *
* @param inputNode * @param index
* The {@link Location} of the input node * The round-robin index of the input node
* @param outputNodes * @param outputNodes
* A {@link Deque} of {@link Location Locations} of the output nodes * A {@link Deque} of {@link Location Locations} of the output nodes
*/ */
private void roundRobinSort(Location inputNode, Deque<Location> outputNodes) { private void roundRobinSort(int index, Deque<Location> outputNodes) {
int index = network.roundRobin.getOrDefault(inputNode, 0);
if (index < outputNodes.size()) { if (index < outputNodes.size()) {
// Not ideal but actually not bad performance-wise over more elegant alternatives // Not ideal but actually not bad performance-wise over more elegant alternatives
for (int i = 0; i < index; i++) { for (int i = 0; i < index; i++) {
Location temp = outputNodes.removeFirst(); Location temp = outputNodes.removeFirst();
outputNodes.add(temp); outputNodes.add(temp);
} }
index++;
} else {
index = 1;
} }
network.roundRobin.put(inputNode, index);
} }
} }