Skip to content

Commit

Permalink
Use fast iterators where possible for fastutils maps
Browse files Browse the repository at this point in the history
  • Loading branch information
pupnewfster committed Feb 23, 2025
1 parent 243568a commit 922adc9
Show file tree
Hide file tree
Showing 29 changed files with 158 additions and 89 deletions.
5 changes: 4 additions & 1 deletion src/api/java/mekanism/api/gear/ModuleData.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import com.mojang.serialization.Codec;
import io.netty.handler.codec.EncoderException;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
Expand Down Expand Up @@ -56,7 +58,8 @@ public ModuleData(ModuleDataBuilder<MODULE> builder) {
this.configData = new Int2ObjectOpenHashMap<>(maxStackSize);
//Handle copying the configs and ensuring the lists are immutable
builder.ensureConfigsInitialized();
for (Int2ObjectMap.Entry<ConfigData> entry : builder.configData.int2ObjectEntrySet()) {
for (ObjectIterator<Int2ObjectMap.Entry<ConfigData>> iterator = Int2ObjectMaps.fastIterator(builder.configData); iterator.hasNext(); ) {
Int2ObjectMap.Entry<ConfigData> entry = iterator.next();
this.configData.put(entry.getIntKey(), entry.getValue().construct());
}
if (this.configData.size() < maxStackSize) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package mekanism.client.lang;

import com.google.common.collect.ImmutableList;
import java.text.ChoiceFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -44,11 +43,11 @@ public static List<Component> split(String text) {
components.add(new TextComponent(text.substring(start)));
}
}
return ImmutableList.copyOf(components);
return List.copyOf(components);
}

public static List<Component> splitMessageFormat(String text) {
return ImmutableList.copyOf(splitMessageFormatInternal(text));
return List.copyOf(splitMessageFormatInternal(text));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package mekanism.common.recipe;

import it.unimi.dsi.fastutil.objects.Object2FloatMap;
import it.unimi.dsi.fastutil.objects.Object2FloatMaps;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.function.Predicate;
import mekanism.api.annotations.NothingNullByDefault;
import mekanism.api.datagen.recipe.MekanismRecipeBuilder;
Expand Down Expand Up @@ -51,7 +53,8 @@ public static void addSmeltingBlastingRecipes(RecipeOutput consumer, Ingredient
public static void addCrusherBioFuelRecipes(RecipeOutput consumer, String basePath, Predicate<String> shouldHandle, @Nullable ICondition condition) {
//Generate baseline recipes from Composter recipe set
//TODO - 1.21: Move these to being "generated" recipes at runtime (maybe behind a config option) that uses the compostable datamap?
for (Object2FloatMap.Entry<ItemLike> chance : ComposterBlock.COMPOSTABLES.object2FloatEntrySet()) {
for (ObjectIterator<Object2FloatMap.Entry<ItemLike>> iterator = Object2FloatMaps.fastIterator(ComposterBlock.COMPOSTABLES); iterator.hasNext(); ) {
Object2FloatMap.Entry<ItemLike> chance = iterator.next();
Item input = chance.getKey().asItem();
ResourceLocation name = RegistryUtils.getName(input);
if (shouldHandle.test(name.getNamespace())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap;
import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap;
import it.unimi.dsi.fastutil.bytes.Byte2ObjectMaps;
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
import it.unimi.dsi.fastutil.bytes.ByteArraySet;
import it.unimi.dsi.fastutil.bytes.ByteIterator;
Expand All @@ -11,6 +12,8 @@
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -183,7 +186,8 @@ record TrackedIngredients<SLOT extends RVRecipeSlot>(SLOT view, Set<HashedItem>
// calculate the split for how we handle maxTransfer by quickly being able to see how many of each type we have
Map<HashedItem, ByteList> matchedItems = new HashMap<>(inputCount);
ByteSet missingSlots = new ByteArraySet(inputCount);
for (Byte2ObjectMap.Entry<TrackedIngredients<SLOT>> entry : hashedIngredients.byte2ObjectEntrySet()) {
for (ObjectIterator<Byte2ObjectMap.Entry<TrackedIngredients<SLOT>>> iterator = Byte2ObjectMaps.fastIterator(hashedIngredients); iterator.hasNext(); ) {
Byte2ObjectMap.Entry<TrackedIngredients<SLOT>> entry = iterator.next();
//TODO: Eventually we probably will want to add in some handling for if an item is valid for more than one slot and one combination
// has it being valid and one combination it is not valid. For example if we have a single piece of stone and it is valid in either
// slot 1 or 2 but slot 2 only allows for stone, and slot 1 can accept granite instead and we have granite available. When coming
Expand Down Expand Up @@ -430,7 +434,8 @@ protected int getRemaining(int slot, ItemStack currentStored) {
}
usedQIOSource.put(source, usedQIO);
}
for (Object2IntMap.Entry<HashedItem> entry : stillLeftOver.object2IntEntrySet()) {
for (ObjectIterator<Object2IntMap.Entry<HashedItem>> iterator = Object2IntMaps.fastIterator(stillLeftOver); iterator.hasNext(); ) {
Object2IntMap.Entry<HashedItem> entry = iterator.next();
availableItemSpace -= entry.getIntValue();
if (availableItemSpace <= 0) {
//No room for all our items, fail
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import it.unimi.dsi.fastutil.objects.Object2BooleanMaps;
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -359,7 +360,8 @@ private ArmorQuads createQuads(Object2BooleanMap<ModuleModelSpec> modules, Set<E
Map<MekanismModelData, Set<String>> allMatchedParts = new Object2ObjectOpenHashMap<>();
for (ModuleOBJModelData modelData : MekanismModelCache.INSTANCE.MEKASUIT_MODULES) {
Set<String> matchedParts = allMatchedParts.computeIfAbsent(modelData, d -> new HashSet<>());
for (Object2BooleanMap.Entry<ModuleModelSpec> entry : modules.object2BooleanEntrySet()) {
for (ObjectIterator<Object2BooleanMap.Entry<ModuleModelSpec>> iterator = Object2BooleanMaps.fastIterator(modules); iterator.hasNext(); ) {
Object2BooleanMap.Entry<ModuleModelSpec> entry = iterator.next();
ModuleModelSpec spec = entry.getKey();
for (String name : modelData.getPartsForSpec(spec, entry.getBooleanValue())) {
if (name.contains(OVERRIDDEN_TAG)) {
Expand Down
30 changes: 17 additions & 13 deletions src/main/java/mekanism/common/attachments/OverflowAware.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import it.unimi.dsi.fastutil.objects.Object2IntSortedMap;
import it.unimi.dsi.fastutil.objects.Object2IntSortedMaps;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.ArrayList;
import java.util.List;
import mekanism.api.SerializationConstants;
Expand All @@ -27,19 +30,20 @@ public record OverflowAware(Object2IntSortedMap<HashedItem> overflow) {

public static final Codec<OverflowAware> CODEC = ItemCount.CODEC.listOf()
.promotePartial(error -> Mekanism.logger.error("Failed to load overflown items: {}", error)).xmap(
counts -> {
Object2IntSortedMap<HashedItem> overflow = new Object2IntLinkedOpenHashMap<>(counts.size());
for (ItemCount itemCount : counts) {
overflow.mergeInt(itemCount.type(), itemCount.count(), Integer::sum);
}
return new OverflowAware(overflow);
}, overflowAware -> {
List<ItemCount> counts = new ArrayList<>(overflowAware.overflow().size());
for (Object2IntMap.Entry<HashedItem> entry : overflowAware.overflow().object2IntEntrySet()) {
counts.add(new ItemCount(entry.getKey(), entry.getIntValue()));
}
return counts;
});
counts -> {
Object2IntSortedMap<HashedItem> overflow = new Object2IntLinkedOpenHashMap<>(counts.size());
for (ItemCount itemCount : counts) {
overflow.mergeInt(itemCount.type(), itemCount.count(), Integer::sum);
}
return new OverflowAware(overflow);
}, overflowAware -> {
List<ItemCount> counts = new ArrayList<>(overflowAware.overflow().size());
for (ObjectIterator<Entry<HashedItem>> iterator = Object2IntMaps.fastIterator(overflowAware.overflow()); iterator.hasNext(); ) {
Object2IntMap.Entry<HashedItem> entry = iterator.next();
counts.add(new ItemCount(entry.getKey(), entry.getIntValue()));
}
return counts;
});
public static final StreamCodec<RegistryFriendlyByteBuf, OverflowAware> STREAM_CODEC = ByteBufCodecs.<RegistryFriendlyByteBuf, HashedItem, Integer, Object2IntSortedMap<HashedItem>>map(
Object2IntLinkedOpenHashMap::new, HashedItem.STREAM_CODEC, ByteBufCodecs.VAR_INT
).map(OverflowAware::new, OverflowAware::overflow);
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/mekanism/common/attachments/qio/DriveContents.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongMaps;
import it.unimi.dsi.fastutil.objects.Object2LongSortedMap;
import it.unimi.dsi.fastutil.objects.Object2LongSortedMaps;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.UUID;
import java.util.function.LongBinaryOperator;
import java.util.stream.LongStream;
Expand Down Expand Up @@ -42,15 +44,17 @@ public static DriveContents create(QIODriveData data) {
return EMPTY;
}
Object2LongSortedMap<UUID> namedItemMap = new Object2LongLinkedOpenHashMap<>(itemMap.size());
for (Object2LongMap.Entry<HashedItem> entry : data.getItemMap().object2LongEntrySet()) {
for (ObjectIterator<Object2LongMap.Entry<HashedItem>> iterator = Object2LongMaps.fastIterator(data.getItemMap()); iterator.hasNext(); ) {
Object2LongMap.Entry<HashedItem> entry = iterator.next();
namedItemMap.put(QIOGlobalItemLookup.INSTANCE.getOrTrackUUID(entry.getKey()), entry.getLongValue());
}
return new DriveContents(namedItemMap);
}

public void loadItemMap(QIODriveData data) {
Object2LongMap<HashedItem> itemMap = data.getItemMap();
for (Object2LongMap.Entry<UUID> entry : namedItemMap.object2LongEntrySet()) {
for (ObjectIterator<Object2LongMap.Entry<UUID>> iterator = Object2LongMaps.fastIterator(namedItemMap); iterator.hasNext(); ) {
Object2LongMap.Entry<UUID> entry = iterator.next();
HashedItem type = QIOGlobalItemLookup.INSTANCE.getTypeByUUID(entry.getKey());
if (type != null) {
//Only add the item if the item type is known. If it can't that means the mod adding the item was probably removed
Expand All @@ -69,7 +73,8 @@ public void loadItemMap(QIODriveData data) {
private long[] serializeItemMap() {
int i = 0;
long[] serializedItemMap = new long[3 * namedItemMap.size()];
for (Object2LongMap.Entry<UUID> entry : namedItemMap.object2LongEntrySet()) {
for (ObjectIterator<Object2LongMap.Entry<UUID>> iterator = Object2LongMaps.fastIterator(namedItemMap); iterator.hasNext(); ) {
Object2LongMap.Entry<UUID> entry = iterator.next();
UUID uuid = entry.getKey();
serializedItemMap[i++] = uuid.getMostSignificantBits();
serializedItemMap[i++] = uuid.getLeastSignificantBits();
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/mekanism/common/config/WorldConfig.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package mekanism.common.config;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -85,7 +84,7 @@ private OreConfig(IMekanismConfig config, ModConfigSpec.Builder builder, OreType
translations.topLevel().applyToBuilder(builder).push(ore);
this.shouldGenerate = CachedBooleanValue.wrap(config, translations.shouldGenerate().applyToBuilder(builder).define("shouldGenerate", true));

Builder<OreVeinConfig> veinBuilder = ImmutableList.builder();
ImmutableList.Builder<OreVeinConfig> veinBuilder = ImmutableList.builder();
for (BaseOreConfig baseConfig : oreType.getBaseConfigs()) {
OreVeinConfigTranslations veinTranslations = OreVeinConfigTranslations.create(ore, baseConfig.name());
veinTranslations.topLevel().applyToBuilder(builder).push(baseConfig.name());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mekanism.common.content.network;

import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
Expand Down Expand Up @@ -45,7 +46,8 @@ public InventoryNetwork(Collection<InventoryNetwork> networks) {
public List<AcceptorData> calculateAcceptors(TransitRequest request, TransporterStack stack, Long2ObjectMap<ChunkAccess> chunkMap,
Map<GlobalPos, Set<TransporterStack>> additionalFlowingStacks, LogisticalTransporterBase start) {
List<AcceptorData> toReturn = new ArrayList<>();
for (Long2ObjectMap.Entry<Map<Direction, IItemHandler>> entry : acceptorCache.getAcceptorEntrySet()) {
for (ObjectIterator<Long2ObjectMap.Entry<Map<Direction, IItemHandler>>> iterator = acceptorCache.getAcceptorFastIterator(); iterator.hasNext(); ) {
Long2ObjectMap.Entry<Map<Direction, IItemHandler>> entry = iterator.next();
long pos = entry.getLongKey();
if (pos != stack.homeLocation) {
BlockPos blockPos = BlockPos.of(pos);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mekanism.common.content.network.transmitter;

import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
Expand Down Expand Up @@ -53,7 +54,7 @@

public abstract class LogisticalTransporterBase extends Transmitter<IItemHandler, InventoryNetwork, LogisticalTransporterBase> {

protected final Int2ObjectOpenHashMap<TransporterStack> transit = new Int2ObjectOpenHashMap<>();
protected final Int2ObjectMap<TransporterStack> transit = new Int2ObjectOpenHashMap<>();
protected final Int2ObjectMap<TransporterStack> needsSync = new Int2ObjectOpenHashMap<>();
public final TransporterTier tier;
protected int nextId = 0;
Expand Down Expand Up @@ -180,14 +181,10 @@ public void onUpdateServer() {
//Note: Our calls to getTileEntity are not done with a chunkMap as we don't tend to have that many tiles we
// are checking at once from here and given this gets called each tick, it would cause unnecessary garbage
// collection to occur actually causing the tick time to go up slightly.
for (ObjectIterator<Int2ObjectMap.Entry<TransporterStack>> iterator = transit.int2ObjectEntrySet().fastIterator(); iterator.hasNext(); ) {
int stackId;
TransporterStack stack;
{
Int2ObjectMap.Entry<TransporterStack> entry = iterator.next();//don't store it anywhere
stackId = entry.getIntKey();
stack = entry.getValue();
}
for (ObjectIterator<Int2ObjectMap.Entry<TransporterStack>> iterator = Int2ObjectMaps.fastIterator(transit); iterator.hasNext(); ) {
Int2ObjectMap.Entry<TransporterStack> entry = iterator.next();//don't store it anywhere
int stackId = entry.getIntKey();
TransporterStack stack = entry.getValue();
if (!stack.initiatedPath) {//Initiate any paths and remove things that can't go places
if (stack.itemStack.isEmpty() || !recalculate(stackId, stack, Long.MAX_VALUE)) {
deletes.add(stackId);
Expand Down Expand Up @@ -339,7 +336,8 @@ public InventoryNetwork createNetworkByMerging(Collection<InventoryNetwork> netw
public CompoundTag getReducedUpdateTag(@NotNull HolderLookup.Provider provider, CompoundTag updateTag) {
updateTag = super.getReducedUpdateTag(provider, updateTag);
ListTag stacks = new ListTag();
for (Int2ObjectMap.Entry<TransporterStack> entry : transit.int2ObjectEntrySet()) {
for (ObjectIterator<Int2ObjectMap.Entry<TransporterStack>> iterator = Int2ObjectMaps.fastIterator(transit); iterator.hasNext(); ) {
Int2ObjectMap.Entry<TransporterStack> entry = iterator.next();
CompoundTag tagCompound = new CompoundTag();
tagCompound.putInt(SerializationConstants.INDEX, entry.getIntKey());
entry.getValue().writeToUpdateTag(provider, this, tagCompound);
Expand Down
Loading

0 comments on commit 922adc9

Please sign in to comment.