From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Wyatt Childers 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 3f7f6a43ac0bf2efb0e66dc96438febbd92113e9..0c2f12e7930646a3da53a50f38be62e0cb1ed2b7 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -435,6 +435,16 @@ 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); @@ -450,15 +460,23 @@ 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 } }