From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: vemacs <d@nkmem.es>
Date: Wed, 23 Nov 2016 08:31:45 -0500
Subject: [PATCH] Cache user authenticator threads


TODO it looks like someone royally messed this one up, patch name doesn't remotely
describe contents. Good thing this patch is no longer relevant at all

no remove queue anymore

diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0597c0c3e881dd43cf91bd3088ed30dfecfe8098..175bf535066afc42de8a3f0d11c46af66f3e3e52 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1388,7 +1388,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
                         }
                     }
 
-                    player.entitiesToRemove.remove(Integer.valueOf(this.entity.getId()));
+                    player.removeQueue.remove(Integer.valueOf(this.entity.getId()));
                     // CraftBukkit end
 
                     if (flag1 && this.trackedPlayerMap.putIfAbsent(player, true) == null) { // Paper
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 3a2356b3e00098d100a179a05316f402390d4e9b..3cde25c2479adcc4ce3014e5ac2ec0710bffeea9 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -4,7 +4,9 @@ import com.google.common.collect.Lists;
 import com.mojang.authlib.GameProfile;
 import com.mojang.datafixers.util.Either;
 import com.mojang.serialization.DataResult;
+import java.util.ArrayDeque; // Paper
 import java.util.Collection;
+import java.util.Deque; // Paper
 import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
@@ -169,7 +171,7 @@ public class ServerPlayer extends Player implements ContainerListener {
     public ServerGamePacketListenerImpl connection;
     public final MinecraftServer server;
     public final ServerPlayerGameMode gameMode;
-    public final List<Integer> entitiesToRemove = Lists.newLinkedList();
+    public final Deque<Integer> removeQueue = new ArrayDeque<>(); // Paper
     private final PlayerAdvancements advancements;
     private final ServerStatsCounter stats;
     private float lastRecordedHealthAndAbsorption = Float.MIN_VALUE;
@@ -544,16 +546,23 @@ public class ServerPlayer extends Player implements ContainerListener {
             this.containerMenu = this.inventoryMenu;
         }
 
-        while (!this.entitiesToRemove.isEmpty()) {
-            int i = Math.min(this.entitiesToRemove.size(), Integer.MAX_VALUE);
+        while (!this.removeQueue.isEmpty()) {
+            int i = Math.min(this.removeQueue.size(), Integer.MAX_VALUE);
             int[] aint = new int[i];
-            Iterator<Integer> iterator = this.entitiesToRemove.iterator();
+            //Iterator<Integer> iterator = this.removeQueue.iterator(); // Paper
             int j = 0;
 
-            while (iterator.hasNext() && j < i) {
+            // Paper start
+            /* while (iterator.hasNext() && j < i) {
                 aint[j++] = (Integer) iterator.next();
                 iterator.remove();
+            } */
+
+            Integer integer;
+            while (j < i && (integer = this.removeQueue.poll()) != null) {
+                aint[j++] = integer.intValue();
             }
+            // Paper end
 
             this.connection.send(new ClientboundRemoveEntitiesPacket(aint));
         }
@@ -1558,7 +1567,14 @@ public class ServerPlayer extends Player implements ContainerListener {
         this.lastSentHealth = -1.0F;
         this.lastSentFood = -1;
         // this.recipeBook.a((RecipeBook) entityplayer.recipeBook); // CraftBukkit
-        this.entitiesToRemove.addAll(oldPlayer.entitiesToRemove);
+        // Paper start - Optimize remove queue - vanilla copies player objects, but CB doesn't. This method currently only
+        // Applies to the same player, so we need to not duplicate our removal queue. The rest of this method does "resetting"
+        // type logic so it does need to be called, maybe? This is silly.
+        // this.removeQueue.addAll(entityplayer.removeQueue);
+        if (this.removeQueue != oldPlayer.removeQueue) {
+            this.removeQueue.addAll(oldPlayer.removeQueue);
+        }
+        // Paper end
         this.seenCredits = oldPlayer.seenCredits;
         this.enteredNetherPosition = oldPlayer.enteredNetherPosition;
         this.setShoulderEntityLeft(oldPlayer.getShoulderEntityLeft());
@@ -1748,13 +1764,13 @@ public class ServerPlayer extends Player implements ContainerListener {
         if (entity instanceof Player) {
             this.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{entity.getId()}));
         } else {
-            this.entitiesToRemove.add((Integer) entity.getId()); // CraftBukkit - decompile error
+            this.removeQueue.add((Integer) entity.getId()); // CraftBukkit - decompile error
         }
 
     }
 
     public void cancelRemoveEntity(Entity entity) {
-        this.entitiesToRemove.remove((Integer) entity.getId()); // CraftBukkit - decompile error
+        this.removeQueue.remove((Integer) entity.getId()); // CraftBukkit - decompile error
     }
 
     @Override
