mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-12-02 15:43:44 +01:00
c09ee99f7e
Closes #257 Ports 2 patches from Purpur: Infinity-bow-settings & Allow-infinite-and-mending-enchantments-together Added an option for infinity with no arrows too. Option for custom locale has come! You can put a locale.json file in your server folder to change it. We've got the finest patches from Hydrinity ( Mykyta approved & allowed ) too. We have some amazing new options in yatopia.yml, we're gonna have documentation for them soon so stay tuned! Last but not least, chunk generation patches. We've tested them extensively so no weirdness happens. Thanks for using Yatopia as your production server software. Co-authored-by: Ivan Pekov <ivan@mrivanplays.com>
141 lines
6.3 KiB
Diff
141 lines
6.3 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..ddd3a071dde9daeebc3d512dd8fd02594d2071fe 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 net.yatopia.server.list.GlueList<>();
|
|
+ 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,23 +91,44 @@ 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 net.yatopia.server.list.GlueList<>(getRecipesMap(recipes).values()));
|
|
+ // Yatopia end
|
|
}
|
|
|
|
public <C extends IInventory, T extends IRecipe<C>> List<T> b(Recipes<T> recipes, C c0, World world) {
|
|
@@ -106,6 +139,7 @@ public class CraftingManager extends ResourceDataJson {
|
|
})).collect(Collectors.toList());
|
|
}
|
|
|
|
+ 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 +161,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 +200,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<>());
|