Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 151 lines 4.6 kB view raw
1package org.bukkit.craftbukkit.util; 2 3import static org.bukkit.craftbukkit.util.Java15Compat.Arrays_copyOf; 4 5import java.util.ArrayList; 6 7import net.minecraft.server.Chunk; 8import net.minecraft.server.MinecraftServer; 9 10import uk.betacraft.uberbukkit.UberbukkitConfig; 11 12public class LongHashtable<V> extends LongHash { 13 Object[][][] values = new Object[256][][]; 14 Entry cache = null; 15 16 public void put(int msw, int lsw, V value) { 17 put(toLong(msw, lsw), value); 18 if (value instanceof Chunk) { 19 Chunk c = (Chunk) value; 20 if (msw != c.x || lsw != c.z) { 21 MinecraftServer.log.info("Chunk (" + c.x + ", " + c.z + ") stored at (" + msw + ", " + lsw + ")"); 22 Throwable x = new Throwable(); 23 x.fillInStackTrace(); 24 x.printStackTrace(); 25 } 26 } 27 } 28 29 public V get(int msw, int lsw) { 30 V value = get(toLong(msw, lsw)); 31 if (value instanceof Chunk) { 32 Chunk c = (Chunk) value; 33 if (msw != c.x || lsw != c.z) { 34 MinecraftServer.log.info("Chunk (" + c.x + ", " + c.z + ") stored at (" + msw + ", " + lsw + ")"); 35 36 if (UberbukkitConfig.getInstance().getBoolean("experimental.force_fix_chunk_coords_corruption", false)) { 37 c.x = msw; 38 c.z = lsw; 39 } else { 40 Throwable x = new Throwable(); 41 x.fillInStackTrace(); 42 x.printStackTrace(); 43 } 44 } 45 } 46 return value; 47 } 48 49 public synchronized void put(long key, V value) { 50 int mainIdx = (int) (key & 255); 51 Object[][] outer = this.values[mainIdx]; 52 if (outer == null) this.values[mainIdx] = outer = new Object[256][]; 53 54 int outerIdx = (int) ((key >> 32) & 255); 55 Object[] inner = outer[outerIdx]; 56 57 if (inner == null) { 58 outer[outerIdx] = inner = new Object[5]; 59 inner[0] = this.cache = new Entry(key, value); 60 } else { 61 int i; 62 for (i = 0; i < inner.length; i++) { 63 if (inner[i] == null || ((Entry) inner[i]).key == key) { 64 inner[i] = this.cache = new Entry(key, value); 65 return; 66 } 67 } 68 69 outer[outerIdx] = inner = Arrays_copyOf(inner, i + i); 70 inner[i] = new Entry(key, value); 71 } 72 } 73 74 public synchronized V get(long key) { 75 return containsKey(key) ? (V) cache.value : null; 76 } 77 78 public synchronized boolean containsKey(long key) { 79 if (this.cache != null && cache.key == key) return true; 80 81 int outerIdx = (int) ((key >> 32) & 255); 82 Object[][] outer = this.values[(int) (key & 255)]; 83 if (outer == null) return false; 84 85 Object[] inner = outer[outerIdx]; 86 if (inner == null) return false; 87 88 for (int i = 0; i < inner.length; i++) { 89 Entry e = (Entry) inner[i]; 90 if (e == null) { 91 return false; 92 } else if (e.key == key) { 93 this.cache = e; 94 return true; 95 } 96 } 97 return false; 98 } 99 100 public synchronized void remove(long key) { 101 Object[][] outer = this.values[(int) (key & 255)]; 102 if (outer == null) return; 103 104 Object[] inner = outer[(int) ((key >> 32) & 255)]; 105 if (inner == null) return; 106 107 for (int i = 0; i < inner.length; i++) { 108 if (inner[i] == null) continue; 109 110 if (((Entry) inner[i]).key == key) { 111 for (i++; i < inner.length; i++) { 112 if (inner[i] == null) break; 113 inner[i - 1] = inner[i]; 114 } 115 116 inner[i - 1] = null; 117 this.cache = null; 118 return; 119 } 120 } 121 } 122 123 public synchronized ArrayList<V> values() { 124 ArrayList<V> ret = new ArrayList<V>(); 125 126 for (Object[][] outer : this.values) { 127 if (outer == null) continue; 128 129 for (Object[] inner : outer) { 130 if (inner == null) continue; 131 132 for (Object entry : inner) { 133 if (entry == null) break; 134 135 ret.add((V) ((Entry) entry).value); 136 } 137 } 138 } 139 return ret; 140 } 141 142 private class Entry { 143 long key; 144 Object value; 145 146 Entry(long k, Object v) { 147 this.key = k; 148 this.value = v; 149 } 150 } 151}