From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
Date: Mon, 29 Jun 2020 17:03:06 -0400
Subject: [PATCH] Remove some streams from structures

This showed up a lot in the spark profiler, should have a low-medium performance improvement.

diff --git a/src/main/java/net/minecraft/world/level/StructureFeatureManager.java b/src/main/java/net/minecraft/world/level/StructureFeatureManager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/StructureFeatureManager.java
+++ b/src/main/java/net/minecraft/world/level/StructureFeatureManager.java
@@ -0,0 +0,0 @@ public class StructureFeatureManager {
         });
     }
 
+    // Paper start - remove structure streams - based on method above
+    public java.util.List<StructureStart<?>> streamlessStartsForFeature(SectionPos sectionPosition, StructureFeature<?> structureGenerator) {
+        java.util.List<StructureStart<?>> list = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+        for (Long curLong : this.level.getChunk(sectionPosition.x(), sectionPosition.z(), ChunkStatus.STRUCTURE_REFERENCES).getReferencesForFeature(structureGenerator)) {
+            SectionPos sectionPosition1 = SectionPos.of(new ChunkPos(curLong), 0);
+            StructureStart<?> structurestart = getStartForFeature(sectionPosition1, structureGenerator, this.level.getChunk(sectionPosition1.x(), sectionPosition1.z(), ChunkStatus.STRUCTURE_STARTS));
+            if (structurestart != null && structurestart.isValid()) {
+                list.add(structurestart);
+            }
+        }
+        return list;
+    }
+    // Paper end
+
     @Nullable
     public StructureStart<?> getStartForFeature(SectionPos pos, StructureFeature<?> feature, FeatureAccess holder) {
         return holder.getStartForFeature(feature);
@@ -0,0 +0,0 @@ public class StructureFeatureManager {
     }
 
     public StructureStart<?> getStructureAt(BlockPos pos, boolean matchChildren, StructureFeature<?> feature) {
-        return (StructureStart) DataFixUtils.orElse(this.startsForFeature(SectionPos.of(pos), feature).filter((structurestart) -> {
-            return matchChildren ? structurestart.getPieces().stream().anyMatch((structurepiece) -> {
-                return structurepiece.getBoundingBox().isInside((Vec3i) pos);
-            }) : structurestart.getBoundingBox().isInside((Vec3i) pos);
-        }).findFirst(), StructureStart.INVALID_START);
+        // Paper start - remove structure streams
+        for (StructureStart<?> structureStart : streamlessStartsForFeature(SectionPos.of(pos), feature)) {
+            if (matchChildren) {
+                for (net.minecraft.world.level.levelgen.structure.StructurePiece piece : structureStart.getPieces()) {
+                    if (piece.getBoundingBox().isInside(pos)) {
+                        return structureStart;
+                    }
+                }
+            } else if (structureStart.getBoundingBox().isInside(pos)) {
+                return structureStart;
+            }
+        }
+        return StructureStart.INVALID_START;
+        // Paper end
     }
 
     // Spigot start
diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/biome/Biome.java
+++ b/src/main/java/net/minecraft/world/level/biome/Biome.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.levelgen.WorldgenRandom;
 import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
 import net.minecraft.world.level.levelgen.feature.StructureFeature;
 import net.minecraft.world.level.levelgen.structure.BoundingBox;
+import net.minecraft.world.level.levelgen.structure.StructureStart;
 import net.minecraft.world.level.levelgen.surfacebuilders.ConfiguredSurfaceBuilder;
 import net.minecraft.world.level.levelgen.synth.PerlinSimplexNoise;
 import net.minecraft.world.level.material.FluidState;
@@ -0,0 +0,0 @@ public final class Biome {
                         int p = region.getMinBuildHeight() + 1;
                         int q = region.getMaxBuildHeight() - 1;
                         region.setCurrentlyGenerating(supplier);
-                        structureAccessor.startsForFeature(SectionPos.of(origin), structureFeature).forEach((structureStart) -> {
+                        // Paper start - remove structure streams
+                        for (StructureStart<?> structureStart : structureAccessor.streamlessStartsForFeature(SectionPos.of(origin), structureFeature)) {
                             structureStart.placeInChunk(region, structureAccessor, chunkGenerator, random, new BoundingBox(n, p, o, n + 15, q, o + 15), new ChunkPos(l, m));
-                        });
+                        }
+                        // Paper end
                     } catch (Exception var24) {
                         CrashReport crashReport = CrashReport.forThrowable(var24, "Feature placement");
                         crashReport.addCategory("Feature").setDetail("Description", supplier::get);
diff --git a/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java b/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
@@ -0,0 +0,0 @@ public class Beardifier {
         this.rigids = new ObjectArrayList<>(10);
 
         for(StructureFeature<?> structureFeature : StructureFeature.NOISE_AFFECTING_FEATURES) {
-            accessor.startsForFeature(SectionPos.bottomOf(chunk), structureFeature).forEach((start) -> {
+            for (net.minecraft.world.level.levelgen.structure.StructureStart<?> start : accessor.streamlessStartsForFeature(SectionPos.of(chunkPos, 0), structureFeature)) { // Paper - remove structure streams
                 for(StructurePiece structurePiece : start.getPieces()) {
                     if (structurePiece.isCloseToChunk(chunkPos, 12)) {
                         if (structurePiece instanceof PoolElementStructurePiece) {
@@ -0,0 +0,0 @@ public class Beardifier {
                     }
                 }
 
-            });
+            } // Paper - remove structure streams
         }
 
         this.pieceIterator = this.rigids.iterator();
