66import net .minecraft .server .world .ChunkLevels ;
77import net .minecraft .util .math .ChunkPos ;
88
9+ import java .util .ArrayDeque ;
10+ import java .util .Queue ;
911import java .util .concurrent .ConcurrentHashMap ;
1012import java .util .concurrent .ConcurrentMap ;
1113import java .util .concurrent .Executor ;
@@ -30,6 +32,9 @@ protected void rehash(int newN) {
3032 private final int id = COUNTER .getAndIncrement ();
3133 private volatile ChunkPos currentSyncLoad = null ;
3234
35+ private boolean consolidatingLevelUpdates = false ;
36+ private Queue <Runnable > consolidatedLevelUpdates = new ArrayDeque <>();
37+
3338 private final Executor executor ;
3439
3540 {
@@ -80,21 +85,52 @@ public Executor positionedExecutor(long pos) {
8085
8186 public void updatePriorityFromLevel (long pos , int level ) {
8287 this .executor .execute (() -> {
83- if (this .getPriorityFromMap (pos ) == level ) return ;
84- final long stamp = this .prioritiesLock .writeLock ();
85- try {
86- if (level < MAX_LEVEL ) {
87- this .prioritiesFromLevel .put (pos , level );
88- } else {
89- this .prioritiesFromLevel .remove (pos );
90- }
91- } finally {
92- this .prioritiesLock .unlockWrite (stamp );
93- }
94- updatePriorityInternal (pos );
88+ updatePriorityFromLevel0 (pos , level );
9589 });
9690 }
9791
92+ private void updatePriorityFromLevel0 (long pos , int level ) {
93+ if (this .getPriorityFromMap (pos ) == level ) return ;
94+ final long stamp = this .prioritiesLock .writeLock ();
95+ try {
96+ if (level < MAX_LEVEL ) {
97+ this .prioritiesFromLevel .put (pos , level );
98+ } else {
99+ this .prioritiesFromLevel .remove (pos );
100+ }
101+ } finally {
102+ this .prioritiesLock .unlockWrite (stamp );
103+ }
104+ updatePriorityInternal (pos );
105+ }
106+
107+ public void updatePriorityFromLevelOnMain (long pos , int level ) {
108+ if (this .consolidatingLevelUpdates ) {
109+ this .consolidatedLevelUpdates .add (() -> updatePriorityFromLevel0 (pos , level ));
110+ } else {
111+ updatePriorityFromLevel (pos , level );
112+ }
113+ }
114+
115+ public void setConsolidatingLevelUpdates (boolean value ) {
116+ this .consolidatingLevelUpdates = value ;
117+ if (!value ) {
118+ if (!this .consolidatedLevelUpdates .isEmpty ()) {
119+ Queue <Runnable > runnables = this .consolidatedLevelUpdates ;
120+ this .consolidatedLevelUpdates = new ArrayDeque <>();
121+ this .executor .execute (() -> {
122+ for (Runnable runnable : runnables ) {
123+ try {
124+ runnable .run ();
125+ } catch (Throwable t ) {
126+ t .printStackTrace ();
127+ }
128+ }
129+ });
130+ }
131+ }
132+ }
133+
98134 private void updatePriorityInternal (long pos ) {
99135 final int priority = getPriority (pos );
100136 final FreeableTaskList locks = this .pos2Tasks .get (pos );
0 commit comments