From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ivan Pekov <ivan@mrivanplays.com>
Date: Tue, 6 Oct 2020 15:10:12 +0300
Subject: [PATCH] Optimize advancement loading

Removed some object allocations and reduced loops

diff --git a/src/main/java/net/minecraft/server/Advancement.java b/src/main/java/net/minecraft/server/Advancement.java
index 384d4090f8ff1ea718de16affa5c146a2f58d28a..486034a826b67c71dc7d07852013dc07fefadb0f 100644
--- a/src/main/java/net/minecraft/server/Advancement.java
+++ b/src/main/java/net/minecraft/server/Advancement.java
@@ -68,6 +68,7 @@ public class Advancement {
         return this.display;
     }
 
+    public final AdvancementRewards getRewards() { return d(); } // Yatopia - OBFHELPER
     public AdvancementRewards d() {
         return this.rewards;
     }
diff --git a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
index eaa1063ff2bc5621e93043c4de41ca62f1323fde..96069438ad3f4b00e2996247c222153228cbc2e1 100644
--- a/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
+++ b/src/main/java/net/minecraft/server/AdvancementDataPlayer.java
@@ -160,11 +160,16 @@ public class AdvancementDataPlayer {
                         throw new JsonParseException("Found null for advancements");
                     }
 
+                    /* // Yatopia start - streams no good
                     Stream<Entry<MinecraftKey, AdvancementProgress>> stream = map.entrySet().stream().sorted(Comparator.comparing(Entry::getValue));
                     Iterator iterator = ((List) stream.collect(Collectors.toList())).iterator();
 
                     while (iterator.hasNext()) {
                         Entry<MinecraftKey, AdvancementProgress> entry = (Entry) iterator.next();
+                     */
+                    Entry<MinecraftKey, AdvancementProgress>[] entries = map.entrySet().toArray(new Entry[0]);
+                    java.util.Arrays.sort(entries, Entry.comparingByValue());
+                    for (Entry<MinecraftKey, AdvancementProgress> entry : entries) { // Yatopia end
                         Advancement advancement = advancementdataworld.a((MinecraftKey) entry.getKey());
 
                         if (advancement == null) {
@@ -202,11 +207,37 @@ public class AdvancementDataPlayer {
             }
         }
 
+        /* // Yatopia start
         this.c(advancementdataworld);
         this.c();
         this.b(advancementdataworld);
+         */
+        loadAdvancements(advancementdataworld);
+        // Yatopia end
     }
 
+    // Yatopia start - reduce overload by post io load of advancements
+    // this combines c(AdvancementDataWorld), c() and b(AdvancementDataWorld) into 1 method
+    // the changes done: loops thru all the advancements only once, does not create an additional list
+    // and does not loop thru the additional list, does not create an additional set when checking for progress and
+    // does not additionally loop thru it
+    private void loadAdvancements(AdvancementDataWorld serverAdvancementManager) {
+        for (Advancement advancement : serverAdvancementManager.getAdvancements()) {
+            if (advancement.getCriteria().isEmpty()) {
+                grantCriteria(advancement, "");
+                advancement.getRewards().a(player); // todo: too lazy to import AdvancementRewards for an obfhelper
+            }
+            AdvancementProgress progress = getProgress(advancement);
+            if (progress.isDone()) {
+                this.j.add(advancement);
+                updateVisibility(advancement);
+                continue; // Do not double check isDone
+            }
+            beginTrackingNoIsDone(advancement, progress);
+        }
+    }
+    // Yatopia end
+
     public void b() {
         if (org.spigotmc.SpigotConfig.disableAdvancementSaving) return; // Spigot
         Map<MinecraftKey, AdvancementProgress> map = Maps.newHashMap();
@@ -331,6 +362,11 @@ public class AdvancementDataPlayer {
         AdvancementProgress advancementprogress = this.getProgress(advancement);
 
         if (!advancementprogress.isDone()) {
+            // Yatopia start - beginTrackig with no isDone check
+            beginTrackingNoIsDone(advancement, advancementprogress);
+        }
+    }
+    private void beginTrackingNoIsDone(Advancement advancement, AdvancementProgress advancementprogress) {
             Iterator iterator = advancement.getCriteria().entrySet().iterator();
 
             while (iterator.hasNext()) {
@@ -350,7 +386,7 @@ public class AdvancementDataPlayer {
                 }
             }
 
-        }
+        //} // Yatopia end
     }
 
     private void d(Advancement advancement) {
@@ -445,6 +481,7 @@ public class AdvancementDataPlayer {
         this.data.put(advancement, advancementprogress);
     }
 
+    private final void updateVisibility(Advancement advancement) { e(advancement); } // Yatopia
     private void e(Advancement advancement) {
         // Paper start
         e(advancement, IterationEntryPoint.ROOT);
