Fixes #3389: Prevent inventory cache from becoming unmatched. (#3390)

Use slightly faster ArrayDeqeue instead of LinkedList.
Check boolean fields before more complex datatypes
This commit is contained in:
yueh
2018-02-17 19:10:09 +01:00
committed by GitHub
parent 22807bc619
commit eed4776c6f
6 changed files with 37 additions and 63 deletions
+1 -1
View File
@@ -320,7 +320,7 @@ public class GridNode implements IGridNode, IPathItem
{ {
final IPathingGrid pg = g.getCache( IPathingGrid.class ); final IPathingGrid pg = g.getCache( IPathingGrid.class );
final IEnergyGrid eg = g.getCache( IEnergyGrid.class ); final IEnergyGrid eg = g.getCache( IEnergyGrid.class );
return this.meetsChannelRequirements() && eg.isNetworkPowered() && !pg.isNetworkBooting(); return eg.isNetworkPowered() && !pg.isNetworkBooting() && this.meetsChannelRequirements();
} }
return false; return false;
} }
+2 -2
View File
@@ -31,7 +31,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Queues;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
@@ -49,7 +49,7 @@ import appeng.me.storage.ItemWatcher;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T> public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{ {
@Nonnull @Nonnull
private static final Deque<NetworkMonitor<?>> GLOBAL_DEPTH = Lists.newLinkedList(); private static final Deque<NetworkMonitor<?>> GLOBAL_DEPTH = Queues.newArrayDeque();
@Nonnull @Nonnull
private final GridStorageCache myGridCache; private final GridStorageCache myGridCache;
+1 -1
View File
@@ -402,7 +402,7 @@ public class PathGridCache implements IPathingGrid
@Override @Override
public boolean isNetworkBooting() public boolean isNetworkBooting()
{ {
return !this.active.isEmpty() && !this.booting; return !this.booting && !this.active.isEmpty();
} }
@Override @Override
@@ -19,9 +19,10 @@
package appeng.me.storage; package appeng.me.storage;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NavigableMap; import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;
@@ -144,7 +145,7 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
public TickRateModulation onTick() public TickRateModulation onTick()
{ {
final LinkedList<IAEItemStack> changes = new LinkedList<>(); final List<IAEItemStack> changes = new ArrayList<>();
this.list.resetStatus(); this.list.resetStatus();
int high = 0; int high = 0;
@@ -259,7 +259,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private static class InventoryCache private static class InventoryCache
{ {
private ItemStack[] cachedStacks = new ItemStack[0];
private IAEItemStack[] cachedAeStacks = new IAEItemStack[0]; private IAEItemStack[] cachedAeStacks = new IAEItemStack[0];
private final IItemHandler itemHandler; private final IItemHandler itemHandler;
@@ -270,68 +269,68 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public List<IAEItemStack> update() public List<IAEItemStack> update()
{ {
List<IAEItemStack> changes = new ArrayList<>(); final List<IAEItemStack> changes = new ArrayList<>();
final int slots = this.itemHandler.getSlots();
int slots = this.itemHandler.getSlots();
// Make room for new slots // Make room for new slots
if( slots > this.cachedStacks.length ) if( slots > this.cachedAeStacks.length )
{ {
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots ); this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
} }
for( int slot = 0; slot < slots; slot++ ) for( int slot = 0; slot < slots; slot++ )
{ {
// Save the old stuff // Save the old stuff
ItemStack oldIS = this.getItemStackInCachedSlot( slot ); final IAEItemStack oldAeIS = this.cachedAeStacks[slot];
IAEItemStack oldAeIS = this.cachedAeStacks[slot]; final ItemStack newIS = this.itemHandler.getStackInSlot( slot );
ItemStack newIS = this.itemHandler.getStackInSlot( slot ); this.handlePossibleSlotChanges( slot, oldAeIS, newIS, changes );
if( isDifferent( newIS, oldIS ) )
{
this.addItemChange( slot, oldAeIS, newIS, changes );
}
else if( !newIS.isEmpty() && !oldIS.isEmpty() )
{
this.addPossibleStackSizeChange( slot, oldAeIS, newIS, changes );
}
} }
// Handle cases where the number of slots actually is lower now than before // Handle cases where the number of slots actually is lower now than before
if( slots < this.cachedStacks.length ) if( slots < this.cachedAeStacks.length )
{ {
for( int slot = slots; slot < this.cachedStacks.length; slot++ ) for( int slot = slots; slot < this.cachedAeStacks.length; slot++ )
{ {
IAEItemStack aeStack = this.cachedAeStacks[slot]; final IAEItemStack aeStack = this.cachedAeStacks[slot];
if( aeStack != null ) if( aeStack != null )
{ {
IAEItemStack a = aeStack.copy(); final IAEItemStack a = aeStack.copy();
a.setStackSize( -a.getStackSize() ); a.setStackSize( -a.getStackSize() );
changes.add( a ); changes.add( a );
} }
} }
// Reduce the cache size // Reduce the cache size
this.cachedStacks = Arrays.copyOf( this.cachedStacks, slots );
this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots ); this.cachedAeStacks = Arrays.copyOf( this.cachedAeStacks, slots );
} }
return changes; return changes;
} }
private void addPossibleStackSizeChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes ) private void handlePossibleSlotChanges( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{
if( oldAeIS != null && oldAeIS.isSameType( newIS ) )
{
this.handleStackSizeChanged( slot, oldAeIS, newIS, changes );
}
else
{
this.handleItemChanged( slot, oldAeIS, newIS, changes );
}
}
private void handleStackSizeChanged( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{ {
// Still the same item, but amount might have changed // Still the same item, but amount might have changed
long diff = newIS.getCount() - oldAeIS.getStackSize(); final long diff = newIS.getCount() - oldAeIS.getStackSize();
if( diff != 0 ) if( diff != 0 )
{ {
IAEItemStack stack = oldAeIS.copy(); final IAEItemStack stack = oldAeIS.copy();
stack.setStackSize( newIS.getCount() ); stack.setStackSize( newIS.getCount() );
this.cachedStacks[slot] = newIS;
this.cachedAeStacks[slot] = stack; this.cachedAeStacks[slot] = stack;
final IAEItemStack a = stack.copy(); final IAEItemStack a = stack.copy();
@@ -340,28 +339,12 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
} }
} }
private ItemStack getItemStackInCachedSlot( int pos ) private void handleItemChanged( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{
if( pos > this.cachedStacks.length )
{
return ItemStack.EMPTY;
}
if( this.cachedStacks[pos] == null )
{
return ItemStack.EMPTY;
}
return this.cachedStacks[pos];
}
private void addItemChange( int slot, IAEItemStack oldAeIS, ItemStack newIS, List<IAEItemStack> changes )
{ {
// Completely different item // Completely different item
this.cachedStacks[slot] = newIS;
this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS ); this.cachedAeStacks[slot] = AEItemStack.fromItemStack( newIS );
// If we had a stack previously in this slot, notify the newtork about its disappearance // If we had a stack previously in this slot, notify the network about its disappearance
if( oldAeIS != null ) if( oldAeIS != null )
{ {
oldAeIS.setStackSize( -oldAeIS.getStackSize() ); oldAeIS.setStackSize( -oldAeIS.getStackSize() );
@@ -374,16 +357,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
changes.add( this.cachedAeStacks[slot] ); changes.add( this.cachedAeStacks[slot] );
} }
} }
private static boolean isDifferent( final ItemStack a, final ItemStack b )
{
if( a == b && b.isEmpty() )
{
return false;
}
return a.isEmpty() || b.isEmpty() || !Platform.itemComparisons().isSameItem( a, b );
}
} }
} }
@@ -294,7 +294,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
@Override @Override
public String toString() public String toString()
{ {
return this.getDefinition().toString(); return this.getStackSize() + "x" + this.getDefinition().getItem().getUnlocalizedName() + "@" + this.getDefinition().getItemDamage();
} }
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
@@ -347,7 +347,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
@Override @Override
public ItemStack asItemStackRepresentation() public ItemStack asItemStackRepresentation()
{ {
return getDefinition().copy(); return this.getDefinition().copy();
} }
@Override @Override