From 05713b26ed30af89668b8899135a7e9e44d5940c Mon Sep 17 00:00:00 2001
From: Mark Whittington <markwhi@gmail.com>
Date: Mon, 24 Mar 2014 01:56:31 -0400
Subject: [PATCH] DynamicNetwork and subclass capacity optimizations

Store the network's capacity on the object rather than calculating it every
time it's requested.  Update the stored value when the network changes.
---
 common/mekanism/api/gas/GasNetwork.java       |  9 ++++++
 .../api/transmitters/DynamicNetwork.java      | 28 +++++++++++++++----
 common/mekanism/common/EnergyNetwork.java     | 24 +++++++++++-----
 common/mekanism/common/FluidNetwork.java      |  9 ++++++
 4 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/common/mekanism/api/gas/GasNetwork.java b/common/mekanism/api/gas/GasNetwork.java
index 7747ce568..a95816f15 100644
--- a/common/mekanism/api/gas/GasNetwork.java
+++ b/common/mekanism/api/gas/GasNetwork.java
@@ -44,12 +44,14 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
 	public GasNetwork(IGridTransmitter<GasNetwork>... varPipes)
 	{
 		transmitters.addAll(Arrays.asList(varPipes));
+		updateCapacity();
 		register();
 	}
 	
 	public GasNetwork(Collection<IGridTransmitter<GasNetwork>> collection)
 	{
 		transmitters.addAll(collection);
+		updateCapacity();
 		register();
 	}
 	
@@ -94,6 +96,7 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
 		
 		gasScale = getScale();
 		
+		updateCapacity();
 		refresh();
 		register();
 	}
@@ -300,6 +303,7 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
 	{
 		Set<IGridTransmitter<GasNetwork>> iterTubes = (Set<IGridTransmitter<GasNetwork>>)transmitters.clone();
 		Iterator<IGridTransmitter<GasNetwork>> it = iterTubes.iterator();
+		boolean networkChanged = false;
 		
 		possibleAcceptors.clear();
 		acceptorDirections.clear();
@@ -311,6 +315,7 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
 			if(conductor == null || ((TileEntity)conductor).isInvalid())
 			{
 				it.remove();
+				networkChanged = true;
 				transmitters.remove(conductor);
 			}
 			else {
@@ -333,6 +338,10 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
 				}
 			}
 		}
+
+		if (networkChanged) {
+			updateCapacity();
+		}
 	}
 
 	@Override
diff --git a/common/mekanism/api/transmitters/DynamicNetwork.java b/common/mekanism/api/transmitters/DynamicNetwork.java
index d575cd21b..6a381cb90 100644
--- a/common/mekanism/api/transmitters/DynamicNetwork.java
+++ b/common/mekanism/api/transmitters/DynamicNetwork.java
@@ -31,6 +31,9 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
 	
 	protected int ticksSinceCreate = 0;
 	
+	protected int capacity = 0;
+	protected double meanCapacity = 0;
+	
 	protected boolean fixed = false;
 	
 	protected boolean needsUpdate = false;
@@ -44,6 +47,7 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
 	public void addAllTransmitters(Set<IGridTransmitter<N>> newTransmitters)
 	{
 		transmitters.addAll(newTransmitters);
+		updateCapacity();
 	}
 	
 	public boolean isFirst(IGridTransmitter<N> transmitter)
@@ -55,6 +59,7 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
 	public void removeTransmitter(IGridTransmitter<N> transmitter)
 	{
 		transmitters.remove(transmitter);
+		updateCapacity();
 		
 		if(transmitters.size() == 0)
 		{
@@ -107,18 +112,31 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
 		return possibleAcceptors.size();
 	}
 
-    public int getCapacity()
-    {
-        return (int)getMeanCapacity() * transmitters.size();
-    }
+	protected synchronized void updateCapacity() {
+		updateMeanCapacity();
+		capacity = (int)meanCapacity * transmitters.size();
+	}
 
     /**
      * Override this if things can have variable capacity along the network.
      * @return An 'average' value of capacity. Calculate it how you will.
      */
+	protected synchronized void updateMeanCapacity() {
+		if (transmitters.size() > 0) {
+			meanCapacity = transmitters.iterator().next().getCapacity();
+		} else {
+			meanCapacity = 0;
+		}
+	}
+	
+    public int getCapacity()
+    {
+    	return capacity;
+    }
+
     public double getMeanCapacity()
     {
-		return transmitters.size() > 0 ? transmitters.iterator().next().getCapacity() : 0;
+    	return meanCapacity;
     }
 	
 	@Override
diff --git a/common/mekanism/common/EnergyNetwork.java b/common/mekanism/common/EnergyNetwork.java
index a397add5f..7fe1c3129 100644
--- a/common/mekanism/common/EnergyNetwork.java
+++ b/common/mekanism/common/EnergyNetwork.java
@@ -38,15 +38,18 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
 	
 	public double electricityStored;
 	
+	
 	public EnergyNetwork(IGridTransmitter<EnergyNetwork>... varCables)
 	{
 		transmitters.addAll(Arrays.asList(varCables));
+		updateCapacity();
 		register();
 	}
 	
 	public EnergyNetwork(Collection<IGridTransmitter<EnergyNetwork>> collection)
 	{
 		transmitters.addAll(collection);
+		updateCapacity();
 		register();
 	}
 	
@@ -81,9 +84,8 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
 	}
 
     @Override
-	public double getMeanCapacity()
+	protected synchronized void updateMeanCapacity()
 	{
-        //Use the harmonic mean. Because we're mean.
         int numCables = transmitters.size();
         double reciprocalSum = 0;
         
@@ -91,8 +93,8 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
         {
             reciprocalSum += 1.0/(double)cable.getCapacity();
         }
-        
-		return (double)numCables / reciprocalSum;
+
+        meanCapacity = (double)numCables / reciprocalSum;            
 	}
     
     @Override
@@ -105,8 +107,9 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
 	    	
 	    	for(EnergyNetwork network : networks)
 	    	{
-	    		caps[networks.indexOf(network)] = network.getCapacity();
-	    		cap += network.getCapacity();
+	    		double networkCapacity = network.getCapacity();
+	    		caps[networks.indexOf(network)] = networkCapacity;
+	    		cap += networkCapacity;
 	    	}
 	    	
 	    	electricityStored = Math.min(cap, electricityStored);
@@ -312,6 +315,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
 	{
 		Set<IGridTransmitter<EnergyNetwork>> iterCables = (Set<IGridTransmitter<EnergyNetwork>>)transmitters.clone();
 		Iterator<IGridTransmitter<EnergyNetwork>> it = iterCables.iterator();
+		boolean networkChanged = false;
 		
 		possibleAcceptors.clear();
 		acceptorDirections.clear();
@@ -324,6 +328,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
 			{
 				it.remove();
 				transmitters.remove(conductor);
+				networkChanged = true;
 			}
 			else {
 				conductor.setTransmitterNetwork(this);
@@ -345,7 +350,11 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
 				}
 			}
 		}
-		
+
+		if (networkChanged) {
+			this.updateCapacity();
+		}
+
 		needsUpdate = true;
 	}
 
@@ -448,6 +457,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
 		network.joulesTransmitted = joulesTransmitted;
 		network.lastPowerScale = lastPowerScale;
 		network.electricityStored += electricityStored;
+		network.updateCapacity();
 		return network;
 	}
 
diff --git a/common/mekanism/common/FluidNetwork.java b/common/mekanism/common/FluidNetwork.java
index 5db6d1193..7eb0ac283 100644
--- a/common/mekanism/common/FluidNetwork.java
+++ b/common/mekanism/common/FluidNetwork.java
@@ -42,12 +42,14 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
 	public FluidNetwork(IGridTransmitter<FluidNetwork>... varPipes)
 	{
 		transmitters.addAll(Arrays.asList(varPipes));
+		updateCapacity();
 		register();
 	}
 	
 	public FluidNetwork(Collection<IGridTransmitter<FluidNetwork>> collection)
 	{
 		transmitters.addAll(collection);
+		updateCapacity();
 		register();
 	}
 	
@@ -92,6 +94,7 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
 		
 		fluidScale = getScale();
 		
+		updateCapacity();
 		refresh();
 		register();
 	}
@@ -295,6 +298,7 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
 	{
 		Set<IGridTransmitter<FluidNetwork>> iterPipes = (Set<IGridTransmitter<FluidNetwork>>)transmitters.clone();
 		Iterator it = iterPipes.iterator();
+		boolean networkChanged = false;
 		
 		possibleAcceptors.clear();
 		acceptorDirections.clear();
@@ -306,6 +310,7 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
 			if(conductor == null || ((TileEntity)conductor).isInvalid())
 			{
 				it.remove();
+				networkChanged = true;
 				transmitters.remove(conductor);
 			}
 			else {
@@ -328,6 +333,10 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
 				}
 			}
 		}
+
+		if(networkChanged) {
+			updateCapacity();
+		}
 	}
 
 	@Override