Fixes #4388: Ensure correct ticking priority order (#4410)

This commit is contained in:
yueh
2020-06-11 20:21:17 +02:00
committed by GitHub
parent d449ee47c4
commit ae69ad6d8a
2 changed files with 61 additions and 56 deletions
+39 -35
View File
@@ -47,6 +47,7 @@ public class TickManagerCache implements ITickManager
private final HashMap<IGridNode, TickTracker> sleeping = new HashMap<>(); private final HashMap<IGridNode, TickTracker> sleeping = new HashMap<>();
private final HashMap<IGridNode, TickTracker> awake = new HashMap<>(); private final HashMap<IGridNode, TickTracker> awake = new HashMap<>();
private final PriorityQueue<TickTracker> upcomingTicks = new PriorityQueue<>(); private final PriorityQueue<TickTracker> upcomingTicks = new PriorityQueue<>();
private long currentTick = 0; private long currentTick = 0;
public TickManagerCache( final IGrid g ) public TickManagerCache( final IGrid g )
@@ -80,50 +81,52 @@ public class TickManagerCache implements ITickManager
public void onUpdateTick() public void onUpdateTick()
{ {
TickTracker tt = null; TickTracker tt = null;
try try
{ {
this.currentTick++; this.currentTick++;
while( !this.upcomingTicks.isEmpty() ) while( !this.upcomingTicks.isEmpty() )
{ {
tt = this.upcomingTicks.peek(); tt = this.upcomingTicks.peek();
final int diff = (int) ( this.currentTick - tt.getLastTick() );
if( diff >= tt.getCurrentRate() ) // Stop once it reaches a TickTracker running at a later tick
if( tt.getNextTick() > this.currentTick )
{ {
// remove tt.. break;
this.upcomingTicks.poll();
final TickRateModulation mod = tt.getGridTickable().tickingRequest( tt.getNode(), diff );
switch( mod )
{
case FASTER:
tt.setRate( tt.getCurrentRate() - 2 );
break;
case IDLE:
tt.setRate( tt.getRequest().maxTickRate );
break;
case SAME:
break;
case SLEEP:
this.sleepDevice( tt.getNode() );
break;
case SLOWER:
tt.setRate( tt.getCurrentRate() + 1 );
break;
case URGENT:
tt.setRate( 0 );
break;
default:
break;
}
if( this.awake.containsKey( tt.getNode() ) )
{
this.addToQueue( tt );
}
} }
else
this.upcomingTicks.poll();
final int diff = (int) ( this.currentTick - tt.getLastTick() );
final TickRateModulation mod = tt.getGridTickable().tickingRequest( tt.getNode(), diff );
switch( mod )
{ {
return; // done! case FASTER:
tt.setCurrentRate( tt.getCurrentRate() - 2 );
break;
case IDLE:
tt.setCurrentRate( tt.getRequest().maxTickRate );
break;
case SAME:
break;
case SLEEP:
this.sleepDevice( tt.getNode() );
break;
case SLOWER:
tt.setCurrentRate( tt.getCurrentRate() + 1 );
break;
case URGENT:
tt.setCurrentRate( 0 );
break;
default:
break;
}
if( this.awake.containsKey( tt.getNode() ) )
{
this.addToQueue( tt );
} }
} }
} }
@@ -255,6 +258,7 @@ public class TickManagerCache implements ITickManager
final TickTracker gt = this.sleeping.get( node ); final TickTracker gt = this.sleeping.get( node );
this.sleeping.remove( node ); this.sleeping.remove( node );
this.awake.put( node, gt ); this.awake.put( node, gt );
this.upcomingTicks.remove( gt );
this.addToQueue( gt ); this.addToQueue( gt );
return true; return true;
+22 -21
View File
@@ -37,7 +37,6 @@ public class TickTracker implements Comparable<TickTracker>
private final TickingRequest request; private final TickingRequest request;
private final IGridTickable gt; private final IGridTickable gt;
private final IGridNode node; private final IGridNode node;
private final TickManagerCache host;
private final long LastFiveTicksTime = 0; private final long LastFiveTicksTime = 0;
@@ -51,7 +50,6 @@ public class TickTracker implements Comparable<TickTracker>
this.node = node; this.node = node;
this.setCurrentRate( ( req.minTickRate + req.maxTickRate ) / 2 ); this.setCurrentRate( ( req.minTickRate + req.maxTickRate ) / 2 );
this.setLastTick( currentTick ); this.setLastTick( currentTick );
this.host = tickManagerCache;
} }
public long getAvgNanos() public long getAvgNanos()
@@ -59,27 +57,25 @@ public class TickTracker implements Comparable<TickTracker>
return( this.LastFiveTicksTime / 5 ); return( this.LastFiveTicksTime / 5 );
} }
public void setRate( final int rate )
{
this.setCurrentRate( rate );
if( this.getCurrentRate() < this.getRequest().minTickRate )
{
this.setCurrentRate( this.getRequest().minTickRate );
}
if( this.getCurrentRate() > this.getRequest().maxTickRate )
{
this.setCurrentRate( this.getRequest().maxTickRate );
}
}
@Override @Override
public int compareTo( @Nonnull final TickTracker t ) public int compareTo( @Nonnull final TickTracker t )
{ {
final int nextTick = (int) ( ( this.getLastTick() - this.host.getCurrentTick() ) + this.getCurrentRate() ); int next = Long.compare( this.getNextTick(), t.getNextTick() );
final int ts_nextTick = (int) ( ( t.getLastTick() - this.host.getCurrentTick() ) + t.getCurrentRate() );
return nextTick - ts_nextTick; if( next != 0 )
{
return next;
}
int last = Long.compare( this.getLastTick(), t.getLastTick() );
if( last != 0 )
{
return last;
}
return Integer.compare( this.getCurrentRate(), t.getCurrentRate() );
} }
public void addEntityCrashInfo( final CrashReportCategory crashreportcategory ) public void addEntityCrashInfo( final CrashReportCategory crashreportcategory )
@@ -111,7 +107,12 @@ public class TickTracker implements Comparable<TickTracker>
public void setCurrentRate( final int currentRate ) public void setCurrentRate( final int currentRate )
{ {
this.currentRate = currentRate; this.currentRate = Math.min( this.getRequest().maxTickRate, Math.max( this.getRequest().minTickRate, currentRate ) );
}
public long getNextTick()
{
return this.lastTick + this.currentRate;
} }
public long getLastTick() public long getLastTick()