From 03b486fc7abc3ecea870b646c13a2a5797ea4796 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 23 Mar 2013 09:29:43 +1100 Subject: [PATCH] LongHash Tweaks. This commit adds a flat array based cache to the LongHash(Set/Map) classes leading to excellent efficiency for servers where most activity is centered around the origin (0,0) --- .../java/org/bukkit/craftbukkit/util/FlatMap.java | 34 ++++++++++++++++++++++ .../org/bukkit/craftbukkit/util/LongHashSet.java | 8 ++++- .../bukkit/craftbukkit/util/LongObjectHashMap.java | 5 ++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/util/FlatMap.java diff --git a/src/main/java/org/bukkit/craftbukkit/util/FlatMap.java b/src/main/java/org/bukkit/craftbukkit/util/FlatMap.java new file mode 100644 index 0000000..e8a7725 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/util/FlatMap.java @@ -0,0 +1,34 @@ +package org.bukkit.craftbukkit.util; + +public class FlatMap { + + private static final int FLAT_LOOKUP_SIZE = 512; + private final Object[][] flatLookup = new Object[FLAT_LOOKUP_SIZE * 2][FLAT_LOOKUP_SIZE * 2]; + + public void put(long msw, long lsw, V value) { + long acx = Math.abs(msw); + long acz = Math.abs(lsw); + if (acx < FLAT_LOOKUP_SIZE && acz < FLAT_LOOKUP_SIZE) { + flatLookup[(int) (msw + FLAT_LOOKUP_SIZE)][(int) (lsw + FLAT_LOOKUP_SIZE)] = value; + } + } + + public void put(long key, V value) { + put(LongHash.msw(key), LongHash.lsw(key), value); + + } + + public V get(long msw, long lsw) { + long acx = Math.abs(msw); + long acz = Math.abs(lsw); + if (acx < FLAT_LOOKUP_SIZE && acz < FLAT_LOOKUP_SIZE) { + return (V) flatLookup[(int) (msw + FLAT_LOOKUP_SIZE)][(int) (lsw + FLAT_LOOKUP_SIZE)]; + } else { + return null; + } + } + + public V get(long key) { + return get(LongHash.msw(key), LongHash.lsw(key)); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java index 22c96c5..331d570 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java @@ -31,6 +31,8 @@ public class LongHashSet { private int elements; private long[] values; private int modCount; + private static final Object PRESENT = new Object(); + private final FlatMap flat = new FlatMap(); public LongHashSet() { this(INITIAL_SIZE); @@ -56,10 +58,12 @@ public class LongHashSet { } public boolean contains(int msw, int lsw) { + if (flat.get(msw, lsw) != null) return true; // Spigot return contains(LongHash.toLong(msw, lsw)); } public boolean contains(long value) { + if (flat.get(value) != null) return true; // Spigot int hash = hash(value); int index = (hash & 0x7FFFFFFF) % values.length; int offset = 1; @@ -82,6 +86,7 @@ public class LongHashSet { } public boolean add(long value) { + flat.put(value, PRESENT); // Spigot int hash = hash(value); int index = (hash & 0x7FFFFFFF) % values.length; int offset = 1; @@ -125,10 +130,11 @@ public class LongHashSet { } public void remove(int msw, int lsw) { + flat.put(msw, lsw, null); // Spigot remove(LongHash.toLong(msw, lsw)); } - public boolean remove(long value) { + private boolean remove(long value) { // Spigot int hash = hash(value); int index = (hash & 0x7FFFFFFF) % values.length; int offset = 1; diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java index 01861cc..dbd33fa 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java @@ -28,6 +28,7 @@ public class LongObjectHashMap implements Cloneable, Serializable { private transient V[][] values; private transient int modCount; private transient int size; + private final FlatMap flat = new FlatMap(); // Spigot public LongObjectHashMap() { initialize(); @@ -61,6 +62,8 @@ public class LongObjectHashMap implements Cloneable, Serializable { } public V get(long key) { + V val = flat.get(key); // Spigot + if (val != null) return val; // Spigot int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); long[] inner = keys[index]; if (inner == null) return null; @@ -78,6 +81,7 @@ public class LongObjectHashMap implements Cloneable, Serializable { } public V put(long key, V value) { + flat.put(key, value); // Spigot int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); long[] innerKeys = keys[index]; V[] innerValues = values[index]; @@ -124,6 +128,7 @@ public class LongObjectHashMap implements Cloneable, Serializable { } public V remove(long key) { + flat.put(key, null); // Spigot int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); long[] inner = keys[index]; if (inner == null) { -- 1.8.2.1