From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 21 Jun 2013 17:13:47 +1000 Subject: [PATCH] LongHash Tweaks Tweaks the LongHash algorithm and provides a large array based map to look up values centered around the origin, ie the access normally seen on a Minecraft server. diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java @@ -0,0 +0,0 @@ public class LongHash { } public static int lsw(long l) { - return (int) (l & 0xFFFFFFFF) + Integer.MIN_VALUE; + return (int) (l) + Integer.MIN_VALUE; // Spigot - remove redundant & } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java @@ -0,0 +0,0 @@ public class LongHashSet { private int elements; private long[] values; private int modCount; + private org.spigotmc.FlatMap flat = new org.spigotmc.FlatMap(); // Spigot public LongHashSet() { this(INITIAL_SIZE); @@ -0,0 +0,0 @@ public class LongHashSet { } public boolean contains(int msw, int lsw) { + // Spigot start + if ( elements == 0 ) + { + return false; + } + if ( flat.contains( msw, lsw ) ) + { + return true; + } + // Spigot end return contains(LongHash.toLong(msw, lsw)); } public boolean contains(long value) { + // Spigot start + if ( elements == 0 ) + { + return false; + } + if ( flat.contains( value ) ) + { + return true; + } + // Spigot end int hash = hash(value); int index = (hash & 0x7FFFFFFF) % values.length; int offset = 1; @@ -0,0 +0,0 @@ public class LongHashSet { } public boolean add(long value) { + flat.put( value, Boolean.TRUE ); // Spigot int hash = hash(value); int index = (hash & 0x7FFFFFFF) % values.length; int offset = 1; @@ -0,0 +0,0 @@ public class LongHashSet { } public void remove(int msw, int lsw) { - remove(LongHash.toLong(msw, lsw)); + // Spigot start + flat.remove(msw, lsw); + remove0(LongHash.toLong(msw, lsw)); } public boolean remove(long value) { + flat.remove(value); + return remove0(value); + } + + private boolean remove0(long value) { + // Spigot end int hash = hash(value); int index = (hash & 0x7FFFFFFF) % values.length; int offset = 1; @@ -0,0 +0,0 @@ public class LongHashSet { freeEntries = values.length; modCount++; + flat = new org.spigotmc.FlatMap(); } public long[] toArray() { diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java @@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable { private transient V[][] values; private transient int modCount; private transient int size; + private transient org.spigotmc.FlatMap flat = new org.spigotmc.FlatMap(); // Spigot public LongObjectHashMap() { initialize(); @@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable { } public V get(long key) { + // Spigot start + if ( size == 0 ) + { + return null; + } + V val = flat.get( key ); + if ( val != null ) + { + return val; + } + // Spigot end int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); long[] inner = keys[index]; if (inner == null) return null; @@ -0,0 +0,0 @@ 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]; @@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable { } public V remove(long key) { + flat.remove(key); // Spigot int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); long[] inner = keys[index]; if (inner == null) { @@ -0,0 +0,0 @@ public class LongObjectHashMap implements Cloneable, Serializable { size = 0; Arrays.fill(keys, null); Arrays.fill(values, null); + flat = new org.spigotmc.FlatMap(); } public Set keySet() { diff --git a/src/main/java/org/spigotmc/FlatMap.java b/src/main/java/org/spigotmc/FlatMap.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 --- /dev/null +++ b/src/main/java/org/spigotmc/FlatMap.java @@ -0,0 +0,0 @@ +package org.spigotmc; + +import org.bukkit.craftbukkit.util.LongHash; + +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 void remove(long key) + { + put( key, null ); + } + + public void remove(long msw, long lsw) + { + put( msw, lsw, null ); + } + + public boolean contains(long msw, long lsw) + { + return get( msw, lsw ) != null; + } + + public boolean contains(long key) + { + return get( key ) != null; + } + + 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 ) ); + } +} --