diff --git a/pom.xml b/pom.xml index e6e1dae02..ad0a33006 100644 --- a/pom.xml +++ b/pom.xml @@ -90,6 +90,14 @@ spoutapi dev-SNAPSHOT + + + net.sf.trove4j + trove4j + 3.0.2 + jar + compile + @@ -173,8 +181,10 @@ com.sk89q:jchronic + net.sf.trove4j:trove4j + true diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java index eae2eb7ae..5b64c5734 100644 --- a/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/src/main/java/com/sk89q/worldedit/EditSession.java @@ -39,6 +39,8 @@ import com.sk89q.worldedit.expression.ExpressionException; import com.sk89q.worldedit.expression.runtime.RValue; import com.sk89q.worldedit.masks.Mask; import com.sk89q.worldedit.patterns.*; +import gnu.trove.set.TIntSet; +import gnu.trove.set.hash.TIntHashSet; /** * This class can wrap all block editing operations into one "edit session" that @@ -118,7 +120,7 @@ public class EditSession { /** * List of missing blocks; */ - private Set missingBlocks = new HashSet(); + private TIntSet missingBlocks = new TIntHashSet(); /** * Mask to cover operations. @@ -660,9 +662,9 @@ public class EditSession { * * @return */ - public Set popMissingBlocks() { - Set missingBlocks = this.missingBlocks; - this.missingBlocks = new HashSet(); + public TIntSet popMissingBlocks() { + TIntSet missingBlocks = this.missingBlocks; + this.missingBlocks = new TIntHashSet(); return missingBlocks; } diff --git a/src/main/java/com/sk89q/worldedit/WorldEdit.java b/src/main/java/com/sk89q/worldedit/WorldEdit.java index 4eff18c76..a84e0efe9 100644 --- a/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -49,6 +49,7 @@ import com.sk89q.worldedit.scripting.*; import com.sk89q.worldedit.tools.*; import com.sk89q.worldedit.masks.*; import com.sk89q.worldedit.patterns.*; +import gnu.trove.set.TIntSet; /** * This class is the main entry point for WorldEdit. All events are routed @@ -974,7 +975,7 @@ public class WorldEdit { blockBag.flushChanges(); } - Set missingBlocks = editSession.popMissingBlocks(); + TIntSet missingBlocks = editSession.popMissingBlocks(); if (missingBlocks.size() > 0) { StringBuilder str = new StringBuilder(); @@ -982,12 +983,12 @@ public class WorldEdit { int size = missingBlocks.size(); int i = 0; - for (Integer id : missingBlocks) { + for (int id : missingBlocks.toArray()) { BlockType type = BlockType.fromID(id); str.append(type != null ? type.getName() + " (" + id + ")" - : id.toString()); + : id); ++i; diff --git a/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java b/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java index 8620c8ccb..44f709fb6 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java +++ b/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java @@ -19,8 +19,8 @@ package com.sk89q.worldedit.blocks; -import java.util.HashMap; -import java.util.Map; +import gnu.trove.map.TIntIntMap; +import gnu.trove.map.hash.TIntIntHashMap; /** * Represents an item. @@ -37,7 +37,7 @@ public class BaseItem { */ private short damage; - private Map enchantments = new HashMap(); + private TIntIntMap enchantments = new TIntIntHashMap(); /** * Construct the object. @@ -88,7 +88,7 @@ public class BaseItem { this.damage = damage; } - public Map getEnchantments() { + public TIntIntMap getEnchantments() { return enchantments; } } diff --git a/src/main/java/com/sk89q/worldedit/blocks/BlockType.java b/src/main/java/com/sk89q/worldedit/blocks/BlockType.java index 0efa94b9f..72f3174e8 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/BlockType.java +++ b/src/main/java/com/sk89q/worldedit/blocks/BlockType.java @@ -19,13 +19,15 @@ package com.sk89q.worldedit.blocks; -import java.util.HashSet; +import java.util.Arrays; import java.util.Map; import java.util.HashMap; -import java.util.EnumSet; import java.util.Map.Entry; import java.util.Random; -import java.util.Set; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.TIntSet; +import gnu.trove.set.hash.TIntHashSet; import com.sk89q.util.StringUtil; import com.sk89q.worldedit.PlayerDirection; @@ -163,7 +165,7 @@ public enum BlockType { /** * Stores a map of the IDs for fast access. */ - private static final Map ids = new HashMap(); + private static BlockType[] ids = new BlockType[256]; /** * Stores a map of the names for fast access. */ @@ -174,8 +176,13 @@ public enum BlockType { private final String[] lookupKeys; static { - for (BlockType type : EnumSet.allOf(BlockType.class)) { - ids.put(type.id, type); + for (BlockType type : values()) { + if (ids.length > type.id) { + ids[type.id] = type; + } else { + ids = Arrays.copyOf(ids, type.id + 10); + ids[type.id] = type; + } for (String key : type.lookupKeys) { lookup.put(key, type); } @@ -214,7 +221,11 @@ public enum BlockType { * @return */ public static BlockType fromID(int id) { - return ids.get(id); + if (id < 0 || id >= ids.length) { + return null; + } else { + return ids[id]; + } } /** @@ -287,7 +298,7 @@ public enum BlockType { /** * HashSet for shouldPlaceLast. */ - private static final Set shouldPlaceLast = new HashSet(); + private static final TIntSet shouldPlaceLast = new TIntHashSet(); static { shouldPlaceLast.add(BlockID.SAPLING); shouldPlaceLast.add(BlockID.BED); @@ -348,7 +359,7 @@ public enum BlockType { /** * HashSet for shouldPlaceLast. */ - private static final Set shouldPlaceFinal = new HashSet(); + private static final TIntSet shouldPlaceFinal = new TIntHashSet(); static { shouldPlaceFinal.add(BlockID.SIGN_POST); shouldPlaceFinal.add(BlockID.WOODEN_DOOR); @@ -376,7 +387,7 @@ public enum BlockType { /** * HashSet for canPassThrough. */ - private static final Set canPassThrough = new HashSet(); + private static final TIntSet canPassThrough = new TIntHashSet(); static { canPassThrough.add(BlockID.AIR); canPassThrough.add(BlockID.WATER); @@ -440,7 +451,7 @@ public enum BlockType { /** * HashSet for usesData. */ - private static final Set usesData = new HashSet(); + private static final TIntSet usesData = new TIntHashSet(); static { usesData.add(BlockID.SAPLING); usesData.add(BlockID.WATER); @@ -532,7 +543,7 @@ public enum BlockType { /** * HashSet for isContainerBlock. */ - private static final Set isContainerBlock = new HashSet(); + private static final TIntSet isContainerBlock = new TIntHashSet(); static { isContainerBlock.add(BlockID.DISPENSER); isContainerBlock.add(BlockID.FURNACE); @@ -563,7 +574,7 @@ public enum BlockType { /** * HashSet for isRedstoneBlock. */ - private static final Set isRedstoneBlock = new HashSet(); + private static final TIntSet isRedstoneBlock = new TIntHashSet(); static { isRedstoneBlock.add(BlockID.POWERED_RAIL); isRedstoneBlock.add(BlockID.DETECTOR_RAIL); @@ -607,7 +618,7 @@ public enum BlockType { /** * HashSet for canTransferRedstone. */ - private static final Set canTransferRedstone = new HashSet(); + private static final TIntSet canTransferRedstone = new TIntHashSet(); static { canTransferRedstone.add(BlockID.REDSTONE_TORCH_OFF); canTransferRedstone.add(BlockID.REDSTONE_TORCH_ON); @@ -640,7 +651,7 @@ public enum BlockType { /** * HashSet for isRedstoneSource. */ - private static final Set isRedstoneSource = new HashSet(); + private static final TIntSet isRedstoneSource = new TIntHashSet(); static { isRedstoneSource.add(BlockID.DETECTOR_RAIL); isRedstoneSource.add(BlockID.REDSTONE_TORCH_OFF); @@ -673,7 +684,7 @@ public enum BlockType { /** * HashSet for isRailBlock. */ - private static final Set isRailBlock = new HashSet(); + private static final TIntSet isRailBlock = new TIntHashSet(); static { isRailBlock.add(BlockID.POWERED_RAIL); isRailBlock.add(BlockID.DETECTOR_RAIL); @@ -702,7 +713,7 @@ public enum BlockType { /** * HashSet for isNaturalBlock. */ - private static final Set isNaturalTerrainBlock = new HashSet(); + private static final TIntSet isNaturalTerrainBlock = new TIntHashSet(); static { isNaturalTerrainBlock.add(BlockID.STONE); isNaturalTerrainBlock.add(BlockID.GRASS); @@ -751,7 +762,7 @@ public enum BlockType { /** * HashSet for emitsLight. */ - private static final Set emitsLight = new HashSet(); + private static final TIntSet emitsLight = new TIntHashSet(); static { emitsLight.add(BlockID.LAVA); emitsLight.add(BlockID.STATIONARY_LAVA); @@ -785,7 +796,7 @@ public enum BlockType { /** * HashSet for isTranslucent. */ - private static final Set isTranslucent = new HashSet(); + private static final TIntSet isTranslucent = new TIntHashSet(); static { isTranslucent.add(BlockID.AIR); isTranslucent.add(BlockID.SAPLING); @@ -1244,8 +1255,8 @@ public enum BlockType { } } - private static final Map dataAttachments = new HashMap(); - private static final Map nonDataAttachments = new HashMap(); + private static final TIntObjectMap dataAttachments = new TIntObjectHashMap(); + private static final TIntObjectMap nonDataAttachments = new TIntObjectHashMap(); static { nonDataAttachments.put(BlockID.SAPLING, PlayerDirection.DOWN); nonDataAttachments.put(BlockID.POWERED_RAIL, PlayerDirection.DOWN); diff --git a/src/main/java/com/sk89q/worldedit/blocks/ItemType.java b/src/main/java/com/sk89q/worldedit/blocks/ItemType.java index 69b94db6c..c8ffca27a 100644 --- a/src/main/java/com/sk89q/worldedit/blocks/ItemType.java +++ b/src/main/java/com/sk89q/worldedit/blocks/ItemType.java @@ -19,15 +19,14 @@ package com.sk89q.worldedit.blocks; -import java.util.HashSet; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; -import java.util.HashMap; -import java.util.EnumSet; import java.util.Map.Entry; -import java.util.Set; import com.sk89q.util.StringUtil; +import gnu.trove.set.TIntSet; +import gnu.trove.set.hash.TIntHashSet; /** * ItemType types. @@ -308,7 +307,7 @@ public enum ItemType { /** * Stores a map of the IDs for fast access. */ - private static final Map ids = new HashMap(); + private static ItemType[] ids = new ItemType[3200]; /** * Stores a map of the names for fast access. */ @@ -319,8 +318,13 @@ public enum ItemType { private final String[] lookupKeys; static { - for (ItemType type : EnumSet.allOf(ItemType.class)) { - ids.put(type.id, type); + for (ItemType type : values()) { + if (ids.length > type.id) { + ids[type.id] = type; + } else { + ids = Arrays.copyOf(ids, type.id + 10); + ids[type.id] = type; + } for (String key : type.lookupKeys) { lookup.put(key, type); } @@ -359,7 +363,11 @@ public enum ItemType { * @return */ public static ItemType fromID(int id) { - return ids.get(id); + if (id < 0 || id >= ids.length) { + return null; + } else { + return ids[id]; + } } /** @@ -369,7 +377,7 @@ public enum ItemType { * @return */ public static String toName(int id) { - ItemType type = ids.get(id); + ItemType type = fromID(id); if (type != null) { return type.getName(); } else { @@ -387,7 +395,7 @@ public enum ItemType { if (id == 0) { return "Hand"; } - ItemType type = ids.get(id); + ItemType type = fromID(id); if (type != null) { return type.getName(); } else { @@ -470,7 +478,7 @@ public enum ItemType { return lookupKeys; } - private static final Set shouldNotStack = new HashSet(); + private static final TIntSet shouldNotStack = new TIntHashSet(); static { shouldNotStack.add(ItemID.IRON_SHOVEL); shouldNotStack.add(ItemID.IRON_PICK); @@ -560,7 +568,7 @@ public enum ItemType { return shouldNotStack.contains(id); } - private static final Set usesDamageValue = new HashSet(); + private static final TIntSet usesDamageValue = new TIntHashSet(); static { usesDamageValue.add(BlockID.SAPLING); //usesDamageValue.add(BlockID.WATER); diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index cd713f6d8..6c3a5a281 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.bukkit; import java.util.HashMap; import java.util.Map; +import gnu.trove.procedure.TIntIntProcedure; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Furnace; @@ -683,13 +684,20 @@ public class BukkitWorld extends LocalWorld { } if (contents[i] != null) { - ItemStack toAdd = new ItemStack(contents[i].getType(), + final ItemStack toAdd = new ItemStack(contents[i].getType(), contents[i].getAmount(), contents[i].getDamage()); try { - for (Map.Entry entry : contents[i].getEnchantments().entrySet()) { - toAdd.addEnchantment(Enchantment.getById(entry.getKey()), entry.getValue()); - } + contents[i].getEnchantments().forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int key, int value) { + Enchantment ench = Enchantment.getById(key); + if (ench != null) { + toAdd.addEnchantment(ench, value); + } + return true; + } + }); } catch (Throwable ignore) {} inven.setItem(i, toAdd); } else {