mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-12-03 08:05:02 +01:00
2b78178637
Upstream/An Sidestream has released updates that appears to apply and compile correctly This update has NOT been tested by YatopiaMC and as with ANY update, please do your own testing. Tuinity Changes: 69e6a4c Updated Upstream (Paper) Purpur Changes: 391f9ad Updated Upstream (Paper)
166 lines
7.5 KiB
Diff
166 lines
7.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Mykyta Komarn <nkomarn@hotmail.com>
|
|
Date: Thu, 1 Oct 2020 06:57:43 -0700
|
|
Subject: [PATCH] Heavily optimize recipe lookups in CraftingManager
|
|
|
|
Recipe lookups are now cached in CraftingManager, which prevent unnecessary ArrayLists being created for every lookup. Additionally, an EMPTY_MAP variable was added to prevent bottlenecks during map creation, since that map is only ever iterated.
|
|
|
|
GlueList was also used as a replacement for ArrayList as it is substantially faster.
|
|
|
|
These changes knock off an extra ~10ms of tick duration with a sample of ~7,700 running furnaces on a server.
|
|
|
|
Co-authored-by: Ivan Pekov <ivan@mrivanplays.com>
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/CraftingManager.java b/src/main/java/net/minecraft/server/CraftingManager.java
|
|
index 58ecbe1e20581dc9e78cdd2f4ece29cfa014da8a..3da86dc56f33e4f1900f6b4f66ca6696eaf6525a 100644
|
|
--- a/src/main/java/net/minecraft/server/CraftingManager.java
|
|
+++ b/src/main/java/net/minecraft/server/CraftingManager.java
|
|
@@ -31,6 +31,10 @@ public class CraftingManager extends ResourceDataJson {
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
|
public Map<Recipes<?>, Object2ObjectLinkedOpenHashMap<MinecraftKey, IRecipe<?>>> recipes = ImmutableMap.of(); // CraftBukkit
|
|
private boolean d;
|
|
+ // Yatopia start
|
|
+ private static final List<IRecipe<?>> ALL_RECIPES_CACHE = new java.util.ArrayList<>();
|
|
+ private static final Map<Recipes<?>, List<IRecipe<?>>> TYPES_CACHE = new Object2ObjectLinkedOpenHashMap<>();
|
|
+ // Yatopia end
|
|
|
|
public CraftingManager() {
|
|
super(CraftingManager.a, "recipes");
|
|
@@ -63,9 +67,17 @@ public class CraftingManager extends ResourceDataJson {
|
|
}
|
|
}
|
|
|
|
+ // Yatopia start - nuke stream & cache all recipes for constant access in b()
|
|
+ /*
|
|
this.recipes = (Map) map1.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry1) -> {
|
|
return entry1.getValue(); // CraftBukkit // Paper - decompile fix - *shrugs internally*
|
|
}));
|
|
+ */
|
|
+ this.recipes = ImmutableMap.copyOf(map1);
|
|
+ for (Object2ObjectLinkedOpenHashMap<MinecraftKey, IRecipe<?>> recipesMap : map1.values()) {
|
|
+ ALL_RECIPES_CACHE.addAll(recipesMap.values());
|
|
+ }
|
|
+ // Yatopia end
|
|
CraftingManager.LOGGER.info("Loaded {} recipes", map1.size());
|
|
}
|
|
|
|
@@ -79,33 +91,65 @@ public class CraftingManager extends ResourceDataJson {
|
|
} else {
|
|
map.putAndMoveToFirst(irecipe.getKey(), irecipe); // CraftBukkit - SPIGOT-4638: last recipe gets priority
|
|
}
|
|
+ ALL_RECIPES_CACHE.add(irecipe); // Yatopia
|
|
}
|
|
// CraftBukkit end
|
|
|
|
public <C extends IInventory, T extends IRecipe<C>> Optional<T> craft(Recipes<T> recipes, C c0, World world) {
|
|
// CraftBukkit start
|
|
+ // Yatopia start - replace stream
|
|
+ /*
|
|
Optional<T> recipe = this.b(recipes).values().stream().flatMap((irecipe) -> {
|
|
return SystemUtils.a(recipes.a(irecipe, world, c0));
|
|
}).findFirst();
|
|
+ */
|
|
+ // Yatopia start - replace stream
|
|
+ Collection<IRecipe<C>> allTypes = this.b(recipes).values();
|
|
+ Optional<T> recipe = Optional.empty();
|
|
+
|
|
+ for (IRecipe<C> possible : allTypes) {
|
|
+ Optional<T> possibleRecipe = recipes.a(possible, world, c0);
|
|
+ if (possibleRecipe.isPresent()) {
|
|
+ recipe = possibleRecipe;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ // Yatopia end
|
|
c0.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found
|
|
// CraftBukkit end
|
|
return recipe;
|
|
}
|
|
|
|
public <C extends IInventory, T extends IRecipe<C>> List<T> a(Recipes<T> recipes) {
|
|
+ // Yatopia start - replaced logic
|
|
+ /*
|
|
return (List) this.b(recipes).values().stream().map((irecipe) -> {
|
|
return irecipe;
|
|
}).collect(Collectors.toList());
|
|
+ */
|
|
+ return (List) TYPES_CACHE.computeIfAbsent(recipes, recipes1 -> new me.jellysquid.mods.lithium.common.util.collections.HashedList<>(new java.util.ArrayList<>(getRecipesMap(recipes).values())));
|
|
+ // Yatopia end
|
|
}
|
|
|
|
public <C extends IInventory, T extends IRecipe<C>> List<T> b(Recipes<T> recipes, C c0, World world) {
|
|
+ // Yatopia start - replace stream
|
|
+ /*
|
|
return (List) this.b(recipes).values().stream().flatMap((irecipe) -> {
|
|
return SystemUtils.a(recipes.a(irecipe, world, c0));
|
|
}).sorted(Comparator.comparing((irecipe) -> {
|
|
return irecipe.getResult().j();
|
|
})).collect(Collectors.toList());
|
|
+ */
|
|
+ List<T> ret = new java.util.ArrayList<>();
|
|
+ for (IRecipe<C> recipe : this.b(recipes).values()) {
|
|
+ recipes.a(recipe, world, c0).ifPresent(ret::add);
|
|
+ }
|
|
+ ret.sort(Comparator.comparing(recipe -> recipe.getResult().getTranslationKey()));
|
|
+ return ret;
|
|
+ // Yatopia end
|
|
}
|
|
|
|
+ private <C extends IInventory, T extends IRecipe<C>> Map<MinecraftKey, IRecipe<C>> getRecipesMap(Recipes<T> recipes) { return b(recipes); } // Yatopia - OBFHELPER
|
|
private <C extends IInventory, T extends IRecipe<C>> Map<MinecraftKey, IRecipe<C>> b(Recipes<T> recipes) {
|
|
return (Map) this.recipes.getOrDefault(recipes, new Object2ObjectLinkedOpenHashMap<>()); // CraftBukkit
|
|
}
|
|
@@ -127,15 +171,26 @@ public class CraftingManager extends ResourceDataJson {
|
|
}
|
|
|
|
public Optional<? extends IRecipe<?>> getRecipe(MinecraftKey minecraftkey) {
|
|
+ // Yatopia start - replace stream
|
|
+ /*
|
|
return this.recipes.values().stream().map((map) -> {
|
|
return map.get(minecraftkey); // CraftBukkit - decompile error
|
|
}).filter(Objects::nonNull).findFirst();
|
|
+ */
|
|
+ for (Map<MinecraftKey, IRecipe<?>> map : recipes.values()) {
|
|
+ IRecipe<?> recipe = map.get(minecraftkey);
|
|
+ if (recipe != null) {
|
|
+ return Optional.of(recipe);
|
|
+ }
|
|
+ }
|
|
+ return Optional.empty();
|
|
+ // Yatopia end
|
|
}
|
|
|
|
public Collection<IRecipe<?>> b() {
|
|
- return (Collection) this.recipes.values().stream().flatMap((map) -> {
|
|
- return map.values().stream();
|
|
- }).collect(Collectors.toSet());
|
|
+ // Yatopia start - O(1) constant complexity
|
|
+ return ALL_RECIPES_CACHE;
|
|
+ // Yatopia end
|
|
}
|
|
|
|
public Stream<MinecraftKey> d() {
|
|
@@ -155,6 +210,10 @@ public class CraftingManager extends ResourceDataJson {
|
|
// CraftBukkit start
|
|
public void clearRecipes() {
|
|
this.recipes = Maps.newHashMap();
|
|
+ // Yatopia start - also clear cache
|
|
+ ALL_RECIPES_CACHE.clear();
|
|
+ TYPES_CACHE.clear();
|
|
+ // Yatopia end
|
|
|
|
for (Recipes<?> recipeType : IRegistry.RECIPE_TYPE) {
|
|
this.recipes.put(recipeType, new Object2ObjectLinkedOpenHashMap<>());
|
|
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
|
|
index 3adb29f004d2fee36f3ee9b21ee5417e84b64837..376ab1d4c4f729639714b5eeedec514a2176531a 100644
|
|
--- a/src/main/java/net/minecraft/server/ItemStack.java
|
|
+++ b/src/main/java/net/minecraft/server/ItemStack.java
|
|
@@ -570,6 +570,7 @@ public final class ItemStack {
|
|
return !this.e() ? this.doMaterialsMatch(itemstack) : !itemstack.isEmpty() && this.getItem() == itemstack.getItem();
|
|
}
|
|
|
|
+ public final String getTranslationKey() { return j(); } // Yatopia - OBFHELPER
|
|
public String j() {
|
|
return this.getItem().f(this);
|
|
}
|