Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 150 lines 4.2 kB view raw
1package org.bukkit.craftbukkit.util; 2 3import java.util.concurrent.locks.ReentrantReadWriteLock; 4import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; 5import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; 6 7import static org.bukkit.craftbukkit.util.Java15Compat.Arrays_copyOf; 8 9public class LongHashset extends LongHash { 10 long[][][] values = new long[256][][]; 11 int count = 0; 12 ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 13 ReadLock rl = rwl.readLock(); 14 WriteLock wl = rwl.writeLock(); 15 16 public boolean isEmpty() { 17 rl.lock(); 18 try { 19 return this.count == 0; 20 } finally { 21 rl.unlock(); 22 } 23 } 24 25 public void add(int msw, int lsw) { 26 add(toLong(msw, lsw)); 27 } 28 29 public void add(long key) { 30 wl.lock(); 31 try { 32 int mainIdx = (int) (key & 255); 33 long outer[][] = this.values[mainIdx]; 34 if (outer == null) this.values[mainIdx] = outer = new long[256][]; 35 36 int outerIdx = (int) ((key >> 32) & 255); 37 long inner[] = outer[outerIdx]; 38 39 if (inner == null) { 40 synchronized (this) { 41 outer[outerIdx] = inner = new long[1]; 42 inner[0] = key; 43 this.count++; 44 } 45 } else { 46 int i; 47 for (i = 0; i < inner.length; i++) { 48 if (inner[i] == key) { 49 return; 50 } 51 } 52 inner = Arrays_copyOf(inner, i + 1); 53 outer[outerIdx] = inner; 54 inner[i] = key; 55 this.count++; 56 } 57 } finally { 58 wl.unlock(); 59 } 60 } 61 62 public boolean containsKey(long key) { 63 rl.lock(); 64 try { 65 long[][] outer = this.values[(int) (key & 255)]; 66 if (outer == null) return false; 67 68 long[] inner = outer[(int) ((key >> 32) & 255)]; 69 if (inner == null) return false; 70 71 for (long entry : inner) { 72 if (entry == key) return true; 73 } 74 return false; 75 } finally { 76 rl.unlock(); 77 } 78 } 79 80 public void remove(long key) { 81 wl.lock(); 82 try { 83 long[][] outer = this.values[(int) (key & 255)]; 84 if (outer == null) return; 85 86 long[] inner = outer[(int) ((key >> 32) & 255)]; 87 if (inner == null) return; 88 89 int max = inner.length - 1; 90 for (int i = 0; i <= max; i++) { 91 if (inner[i] == key) { 92 this.count--; 93 if (i != max) { 94 inner[i] = inner[max]; 95 } 96 97 outer[(int) ((key >> 32) & 255)] = (max == 0 ? null : Arrays_copyOf(inner, max)); 98 return; 99 } 100 } 101 } finally { 102 wl.unlock(); 103 } 104 } 105 106 public long popFirst() { 107 wl.lock(); 108 try { 109 for (long[][] outer : this.values) { 110 if (outer == null) continue; 111 112 for (int i = 0; i < outer.length; i++) { 113 long[] inner = outer[i]; 114 if (inner == null || inner.length == 0) continue; 115 116 this.count--; 117 long ret = inner[inner.length - 1]; 118 outer[i] = Arrays_copyOf(inner, inner.length - 1); 119 120 return ret; 121 } 122 } 123 } finally { 124 wl.unlock(); 125 } 126 return 0; 127 } 128 129 public long[] keys() { 130 int index = 0; 131 rl.lock(); 132 try { 133 long[] ret = new long[this.count]; 134 for (long[][] outer : this.values) { 135 if (outer == null) continue; 136 137 for (long[] inner : outer) { 138 if (inner == null) continue; 139 140 for (long entry : inner) { 141 ret[index++] = entry; 142 } 143 } 144 } 145 return ret; 146 } finally { 147 rl.unlock(); 148 } 149 } 150}