mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-27 04:55:47 +01:00
226 lines
6.9 KiB
Diff
226 lines
6.9 KiB
Diff
|
From 0759031a2d3ef71799dbb5ac0b5b7f5cff54fd4f Mon Sep 17 00:00:00 2001
|
||
|
From: md_5 <md_5@live.com.au>
|
||
|
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 691cafd..9d54472 100644
|
||
|
--- a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
|
||
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
|
||
|
@@ -10,6 +10,6 @@ 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 22c96c5..7f659b7 100644
|
||
|
--- a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
|
||
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
|
||
|
@@ -31,6 +31,7 @@ public class LongHashSet {
|
||
|
private int elements;
|
||
|
private long[] values;
|
||
|
private int modCount;
|
||
|
+ private org.spigotmc.FlatMap<Boolean> flat = new org.spigotmc.FlatMap<Boolean>(); // Spigot
|
||
|
|
||
|
public LongHashSet() {
|
||
|
this(INITIAL_SIZE);
|
||
|
@@ -56,10 +57,30 @@ 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;
|
||
|
@@ -82,6 +103,7 @@ 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;
|
||
|
@@ -125,10 +147,18 @@ 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;
|
||
|
@@ -161,6 +191,7 @@ public class LongHashSet {
|
||
|
|
||
|
freeEntries = values.length;
|
||
|
modCount++;
|
||
|
+ flat = new org.spigotmc.FlatMap<Boolean>();
|
||
|
}
|
||
|
|
||
|
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 01861cc..2e5b436 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<V> implements Cloneable, Serializable {
|
||
|
private transient V[][] values;
|
||
|
private transient int modCount;
|
||
|
private transient int size;
|
||
|
+ private transient org.spigotmc.FlatMap<V> flat = new org.spigotmc.FlatMap<V>(); // Spigot
|
||
|
|
||
|
public LongObjectHashMap() {
|
||
|
initialize();
|
||
|
@@ -61,6 +62,17 @@ public class LongObjectHashMap<V> 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;
|
||
|
@@ -78,6 +90,7 @@ public class LongObjectHashMap<V> 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 +137,7 @@ public class LongObjectHashMap<V> 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) {
|
||
|
@@ -174,6 +188,7 @@ public class LongObjectHashMap<V> implements Cloneable, Serializable {
|
||
|
size = 0;
|
||
|
Arrays.fill(keys, null);
|
||
|
Arrays.fill(values, null);
|
||
|
+ flat = new org.spigotmc.FlatMap<V>();
|
||
|
}
|
||
|
|
||
|
public Set<Long> keySet() {
|
||
|
diff --git a/src/main/java/org/spigotmc/FlatMap.java b/src/main/java/org/spigotmc/FlatMap.java
|
||
|
new file mode 100644
|
||
|
index 0000000..9416f6e
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/org/spigotmc/FlatMap.java
|
||
|
@@ -0,0 +1,64 @@
|
||
|
+package org.spigotmc;
|
||
|
+
|
||
|
+import org.bukkit.craftbukkit.util.LongHash;
|
||
|
+
|
||
|
+public class FlatMap<V>
|
||
|
+{
|
||
|
+
|
||
|
+ 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 ) );
|
||
|
+ }
|
||
|
+}
|
||
|
--
|
||
|
1.9.1
|
||
|
|