attempt at pattern rebuild optimization

This commit is contained in:
PrototypeTrousers
2022-02-22 00:02:17 -03:00
parent ee9441474e
commit 30f4cdf545
5 changed files with 82 additions and 75 deletions
@@ -427,6 +427,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return;
}
boolean removed = false;
if( this.craftingList != null )
{
final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator();
@@ -446,26 +448,36 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( !found )
{
removed = true;
i.remove();
}
}
}
boolean newPattern = false;
for( int x = 0; x < accountedFor.length; x++ )
{
if( !accountedFor[x] )
{
newPattern = true;
this.addToCraftingList( this.patterns.getStackInSlot( x ) );
}
}
try
{
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
if( removed )
{
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
}
else if( newPattern )
{
this.provideCrafting( (ICraftingProviderHelper) this.gridProxy.getCrafting() );
}
}
catch( final GridAccessException e )
catch( GridAccessException e )
{
// :P
e.printStackTrace();
}
}
@@ -549,7 +561,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
try
{
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
this.gridProxy.getTick().wakeDevice( this.gridProxy.getNode() );
}
catch( final GridAccessException e )
+10 -7
View File
@@ -30,6 +30,7 @@ import java.util.Queue;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.google.common.base.Stopwatch;
import com.google.common.collect.LinkedListMultimap;
@@ -190,10 +191,11 @@ public class TickHandler
synchronized ( this.craftingJobs )
{
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
if (!jobSet.isEmpty()) {
if( !jobSet.isEmpty() )
{
final int jobSize = jobSet.size();
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
final int simTime = Math.max(1, microSecondsPerTick / jobSize);
final int simTime = Math.max( 1, microSecondsPerTick / jobSize );
jobSet.removeIf( cj -> !cj.simulateFor( simTime ) );
}
@@ -206,7 +208,7 @@ public class TickHandler
this.tickColors( this.srvPlayerColors );
// ready tiles.
final HandlerRep repo = this.getRepo();
while( !repo.tiles.isEmpty() )
while ( !repo.tiles.isEmpty() )
{
final AEBaseTile bt = repo.tiles.poll();
if( !bt.isInvalid() )
@@ -217,7 +219,8 @@ public class TickHandler
// tick networks.
this.getRepo().updateNetworks();
for( final Grid g : this.getRepo().networks )
List<Grid> grids = new ArrayList<>( this.getRepo().networks );
for( final Grid g : grids )
{
g.update();
}
@@ -238,7 +241,7 @@ public class TickHandler
private void tickColors( final HashMap<Integer, PlayerColor> playerSet )
{
final Iterator<PlayerColor> i = playerSet.values().iterator();
while( i.hasNext() )
while ( i.hasNext() )
{
final PlayerColor pc = i.next();
if( pc.ticksLeft <= 0 )
@@ -259,7 +262,7 @@ public class TickHandler
final Stopwatch sw = Stopwatch.createStarted();
IWorldCallable<?> c = null;
while( ( c = queue.poll() ) != null )
while ( ( c = queue.poll() ) != null )
{
try
{
@@ -283,7 +286,7 @@ public class TickHandler
public void registerCraftingSimulation( final World world, final CraftingJob craftingJob )
{
synchronized( this.craftingJobs )
synchronized ( this.craftingJobs )
{
this.craftingJobs.put( world, craftingJob );
}
+1 -7
View File
@@ -19,12 +19,8 @@
package appeng.me;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Set;
import appeng.api.AEApi;
import appeng.api.networking.IGrid;
@@ -220,9 +216,7 @@ public class Grid implements IGrid
@Override
public MENetworkEvent postEvent( final MENetworkEvent ev )
{
CraftingGridCache.pauseRebuilds();
final MENetworkEvent ret = this.eventBus.postEvent( this, ev );
CraftingGridCache.unpauseRebuilds();
return ret;
}
+6 -9
View File
@@ -65,7 +65,7 @@ import net.minecraftforge.common.util.Constants;
public class GridNode implements IGridNode, IPathItem
{
private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged();
private static final int[] CHANNEL_COUNT = { 0, 8, 32 };
private static final int[] CHANNEL_COUNT = {0, 8, 32};
private final List<IGridConnection> connections = new ArrayList<>();
private final IGridBlock gridProxy;
@@ -166,8 +166,6 @@ public class GridNode implements IGridNode, IPathItem
{
final Object tracker = new Object();
CraftingGridCache.pauseRebuilds();
Deque<GridNode> nextRun = new ArrayDeque<>();
nextRun.add( this );
@@ -178,9 +176,9 @@ public class GridNode implements IGridNode, IPathItem
final Deque<IGridConnection> nextConn = new ArrayDeque<>();
final IGridConnectionVisitor gcv = (IGridConnectionVisitor) g;
while( !nextRun.isEmpty() )
while ( !nextRun.isEmpty() )
{
while( !nextConn.isEmpty() )
while ( !nextConn.isEmpty() )
{
gcv.visitConnection( nextConn.poll() );
}
@@ -196,7 +194,7 @@ public class GridNode implements IGridNode, IPathItem
}
else
{
while( !nextRun.isEmpty() )
while ( !nextRun.isEmpty() )
{
final Iterable<GridNode> thisRun = nextRun;
nextRun = new ArrayDeque<>();
@@ -207,7 +205,6 @@ public class GridNode implements IGridNode, IPathItem
}
}
}
CraftingGridCache.unpauseRebuilds();
}
@Override
@@ -269,7 +266,7 @@ public class GridNode implements IGridNode, IPathItem
@Override
public void destroy()
{
while( !this.connections.isEmpty() )
while ( !this.connections.isEmpty() )
{
// not part of this network for real anymore.
if( this.connections.size() == 1 )
@@ -378,7 +375,7 @@ public class GridNode implements IGridNode, IPathItem
@Override
public boolean meetsChannelRequirements()
{
return( !this.gridProxy.getFlags().contains( GridFlags.REQUIRE_CHANNEL ) || this.getUsedChannels() > 0 );
return ( !this.gridProxy.getFlags().contains( GridFlags.REQUIRE_CHANNEL ) || this.getUsedChannels() > 0 );
}
@Override
+49 -47
View File
@@ -113,9 +113,9 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
private final GenericInterestManager<CraftingWatcher> interestManager = new GenericInterestManager<>( this.interests );
private IStorageGrid storageGrid;
private IEnergyGrid energyGrid;
int i;
private boolean updateList = false;
private static int pauseRebuilds = 0;
private static Set<CraftingGridCache> rebuildNeeded = new HashSet<>();
private boolean updatePatterns = true;
public CraftingGridCache( final IGrid grid )
{
@@ -140,8 +140,14 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
this.updateCPUClusters();
}
if( updatePatterns )
{
this.recalculateCraftingPatterns();
this.updatePatterns = false;
}
final Iterator<CraftingLinkNexus> craftingLinkIterator = this.craftingLinks.values().iterator();
while( craftingLinkIterator.hasNext() )
while ( craftingLinkIterator.hasNext() )
{
if( craftingLinkIterator.next().isDead( this.grid, this ) )
{
@@ -187,7 +193,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider )
{
this.craftingProviders.remove( machine );
this.updatePatterns();
this.updatePatterns = true;
}
}
@@ -221,7 +227,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider )
{
this.craftingProviders.add( (ICraftingProvider) machine );
this.updatePatterns();
this.updatePatterns = true;
}
}
@@ -242,36 +248,15 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// nothing!
}
public static void pauseRebuilds()
{
pauseRebuilds++;
}
public static void unpauseRebuilds()
{
pauseRebuilds--;
if (pauseRebuilds == 0 && rebuildNeeded.size() > 0)
{
ImmutableSet<CraftingGridCache> needed = ImmutableSet.copyOf(rebuildNeeded);
rebuildNeeded.clear();
for ( CraftingGridCache cache: needed )
{
cache.updatePatterns();
}
}
}
private void updatePatterns()
{
// coalesce change events during a grid traversal to a single rebuild
if (pauseRebuilds != 0)
{
rebuildNeeded.add(this);
return;
}
this.updatePatterns = true;
}
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>(this.craftableItems);
final Set<IAEItemStack> oldEmitableItems = new HashSet<>(this.emitableItems);
private void recalculateCraftingPatterns()
{
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>( this.craftableItems );
final Set<IAEItemStack> oldEmitableItems = new HashSet<>( this.emitableItems );
// erase list.
this.craftingMethods.clear();
@@ -312,25 +297,29 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
}
Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftablesChanged = new Object2ObjectArrayMap<>();
List<IAEItemStack> craftablesChanged = new ArrayList<>();
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) {
if (!this.craftableItems.containsKey( ais.getKey() )) {
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i )
{
if( !this.craftableItems.containsKey( ais.getKey() ) )
{
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.put( changedStack, ais.getValue() );
craftablesChanged.add( changedStack );
}
}
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) {
if (!oldItems.containsKey( ais )){
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j )
{
if( !oldItems.containsKey( ais ) )
{
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.put( changedStack, ais.getValue() );
craftablesChanged.add( changedStack );
}
}
@@ -341,7 +330,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.put( changedStack, null );
craftablesChanged.add( changedStack );
}
}
@@ -352,12 +341,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.put( changedStack, null );
craftablesChanged.add( changedStack );
}
}
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
new BaseActionSource() );
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged, new BaseActionSource() );
}
private void updateCPUClusters()
@@ -423,6 +411,21 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
{
details.add( medium );
}
if( !updatePatterns )
{
List<IAEItemStack> newCraftables = new ArrayList<>();
for( IAEItemStack stack : api.getOutputs() )
{
ImmutableList<ICraftingPatternDetails> a = this.craftableItems.get( stack );
if( a == null || a.get( 0 ).getPriority() < api.getPriority() )
{
this.craftableItems.put( stack, ImmutableList.of( api ) );
newCraftables.add( stack.copy().reset().setCraftable( true ) );
}
}
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), newCraftables, new BaseActionSource() );
}
}
@Override
@@ -596,8 +599,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
}
}
Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) ->
{
Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) -> {
if( prioritizePower )
{
final int comparison1 = Long.compare( nextCluster.getCoProcessors(), firstCluster.getCoProcessors() );
@@ -676,7 +678,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
public boolean hasCpu( final ICraftingCPU cpu )
{
if (cpu instanceof CraftingCPUCluster)
if( cpu instanceof CraftingCPUCluster )
{
return this.craftingCPUClusters.contains( (CraftingCPUCluster) cpu );
}
@@ -710,7 +712,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
private void findNext()
{
while( this.iterator.hasNext() && this.cpuCluster == null )
while ( this.iterator.hasNext() && this.cpuCluster == null )
{
this.cpuCluster = this.iterator.next();
if( !this.cpuCluster.isActive() || this.cpuCluster.isDestroyed() )