54 lines
		
	
	
	
		
			2.4 KiB
			
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			54 lines
		
	
	
	
		
			2.4 KiB
			
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
						|
From: Wyatt Childers <wchilders@nearce.com>
 | 
						|
Date: Sat, 4 Jul 2020 23:07:43 -0400
 | 
						|
Subject: [PATCH] Optimize the advancement data player iteration to be O(N)
 | 
						|
 rather than O(N^2)
 | 
						|
 | 
						|
 | 
						|
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
 | 
						|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
						|
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
 | 
						|
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
 | 
						|
@@ -0,0 +0,0 @@ public class PlayerAdvancements {
 | 
						|
     }
 | 
						|
 
 | 
						|
     private void ensureVisibility(Advancement advancement) {
 | 
						|
+        // Paper start
 | 
						|
+        ensureVisibility(advancement, IterationEntryPoint.ROOT);
 | 
						|
+    }
 | 
						|
+    private enum IterationEntryPoint {
 | 
						|
+        ROOT,
 | 
						|
+        ITERATOR,
 | 
						|
+        PARENT_OF_ITERATOR
 | 
						|
+    }
 | 
						|
+    private void ensureVisibility(Advancement advancement, IterationEntryPoint entryPoint) {
 | 
						|
+        // Paper end
 | 
						|
         boolean flag = this.shouldBeVisible(advancement);
 | 
						|
         boolean flag1 = this.visible.contains(advancement);
 | 
						|
 
 | 
						|
@@ -0,0 +0,0 @@ public class PlayerAdvancements {
 | 
						|
         }
 | 
						|
 
 | 
						|
         if (flag != flag1 && advancement.getParent() != null) {
 | 
						|
-            this.ensureVisibility(advancement.getParent());
 | 
						|
+            // Paper start - If we're not coming from an iterator consider this to be a root entry, otherwise
 | 
						|
+            // market that we're entering from the parent of an iterator.
 | 
						|
+            this.ensureVisibility(advancement.getParent(), entryPoint == IterationEntryPoint.ITERATOR ? IterationEntryPoint.PARENT_OF_ITERATOR : IterationEntryPoint.ROOT);
 | 
						|
         }
 | 
						|
 
 | 
						|
+        // If this is true, we've went through a child iteration, entered the parent, processed the parent
 | 
						|
+        // and are about to reprocess the children. Stop processing here to prevent O(N^2) processing.
 | 
						|
+        if (entryPoint == IterationEntryPoint.PARENT_OF_ITERATOR) {
 | 
						|
+            return;
 | 
						|
+        } // Paper end
 | 
						|
+
 | 
						|
         Iterator iterator = advancement.getChildren().iterator();
 | 
						|
 
 | 
						|
         while (iterator.hasNext()) {
 | 
						|
             Advancement advancement1 = (Advancement) iterator.next();
 | 
						|
 
 | 
						|
-            this.ensureVisibility(advancement1);
 | 
						|
+            this.ensureVisibility(advancement1, IterationEntryPoint.ITERATOR); // Paper - Mark this call as being from iteration
 | 
						|
         }
 | 
						|
 
 | 
						|
     }
 |