diff options
author | Tahg <tahgtahv@gmail.com> | 2011-03-07 13:43:26 -0500 |
---|---|---|
committer | Tahg <tahgtahv@gmail.com> | 2011-03-10 13:04:59 -0500 |
commit | 67cf10656c4328164331a2411286f5045ec6f6d9 (patch) | |
tree | fb500345e5f34e61e2ae0c5ec8b3af6d3be8af46 | |
parent | 54a05f3ce2a06b5700b7d08aa24bad20dc114ac5 (diff) | |
download | craftbukkit-67cf10656c4328164331a2411286f5045ec6f6d9.tar craftbukkit-67cf10656c4328164331a2411286f5045ec6f6d9.tar.gz craftbukkit-67cf10656c4328164331a2411286f5045ec6f6d9.tar.lz craftbukkit-67cf10656c4328164331a2411286f5045ec6f6d9.tar.xz craftbukkit-67cf10656c4328164331a2411286f5045ec6f6d9.zip |
Add locks to Hashset
-rw-r--r-- | src/main/java/org/bukkit/craftbukkit/util/LongHashset.java | 191 |
1 files changed, 128 insertions, 63 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHashset.java b/src/main/java/org/bukkit/craftbukkit/util/LongHashset.java index 2f8c2ccb..4422ec07 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongHashset.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongHashset.java @@ -1,14 +1,27 @@ package org.bukkit.craftbukkit.util; + import static org.bukkit.craftbukkit.util.Java15Compat.Arrays_copyOf; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; +import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; -public class LongHashset extends LongHash { +public class LongHashset extends LongHash +{ long values[][][] = new long[256][][]; int count = 0; - + ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + ReadLock rl = rwl.readLock(); + WriteLock wl = rwl.writeLock(); + public boolean isEmpty() { - return count == 0; + rl.lock(); + try { + return count == 0; + } finally { + rl.unlock(); + } } - + public void add(int msw, int lsw) { add(toLong(msw, lsw)); } @@ -16,90 +29,142 @@ public class LongHashset extends LongHash { public void add(long key) { int mainIdx = (int) (key & 255); int outerIdx = (int) ((key >> 32) & 255); - long outer[][] = values[mainIdx], inner[]; - if(outer == null) values[mainIdx] = outer = new long[256][]; - inner = outer[outerIdx]; - if(inner == null) { - outer[outerIdx] = inner = new long[1]; - inner[0] = key; - count++; - } - else { - int i; - for(i = 0; i < inner.length; i++) { - if(inner[i] == key) { - return; + rl.lock(); + try { + wl.lock(); + try { + long outer[][] = values[mainIdx], inner[]; + if (outer == null) + values[mainIdx] = outer = new long[256][]; + inner = outer[outerIdx]; + if (inner == null) { + synchronized (this) { + outer[outerIdx] = inner = new long[1]; + inner[0] = key; + count++; + } + } else { + int i; + for (i = 0; i < inner.length; i++) { + if (inner[i] == key) { + return; + } + } + inner = Arrays_copyOf(inner, i + 1); + outer[outerIdx] = inner; + inner[i] = key; + count++; } + } finally { + wl.unlock(); } - outer[outerIdx] = inner = Arrays_copyOf(inner, i+1); - inner[i] = key; - count++; + } finally { + rl.unlock(); } } - + public boolean containsKey(long key) { int mainIdx = (int) (key & 255); int outerIdx = (int) ((key >> 32) & 255); - long outer[][] = values[mainIdx], inner[]; - if(outer == null) return false; - inner = outer[outerIdx]; - if(inner == null) return false; - else { - for(long entry : inner) { - if(entry == key) return true; + rl.lock(); + try { + long outer[][] = values[mainIdx], inner[]; + if (outer == null) + return false; + inner = outer[outerIdx]; + if (inner == null) + return false; + else { + for (long entry : inner) { + if (entry == key) + return true; + } + return false; } - return false; + } finally { + rl.unlock(); } } - + public void remove(long key) { - long[][] outer = this.values[(int) (key & 255)]; - if (outer == null) return; + rl.lock(); + try { + long[][] outer = this.values[(int) (key & 255)]; + if (outer == null) + return; - long[] inner = outer[(int) ((key >> 32) & 255)]; - if (inner == null) return; - - int max = inner.length - 1; - for(int i = 0; i <= max; i++) { - if(inner[i] == key) { - count--; - if(i != max) { - inner[i] = inner[max]; - } - outer[(int) ((key >> 32) & 255)] = (max == 0 ? null : Arrays_copyOf(inner, max)); + long[] inner = outer[(int) ((key >> 32) & 255)]; + if (inner == null) return; + + int max = inner.length - 1; + for (int i = 0; i <= max; i++) { + if (inner[i] == key) { + wl.lock(); + try { + count--; + if (i != max) { + inner[i] = inner[max]; + } + outer[(int) ((key >> 32) & 255)] = (max == 0 ? null : Arrays_copyOf(inner, max)); + } finally { + wl.unlock(); + } + return; + } } + } finally { + rl.unlock(); } } - + public long popFirst() { - for(long[][] outer : values) { - if(outer == null) continue; - for(int i = 0; i < outer.length ; i++) { - long[] inner = outer[i]; - if(inner == null || inner.length == 0) continue; - count--; - long ret = inner[inner.length - 1]; - outer[i] = Arrays_copyOf(inner, inner.length - 1); - return ret; - + rl.lock(); + try { + for (long[][] outer : values) { + if (outer == null) + continue; + for (int i = 0; i < outer.length; i++) { + long[] inner = outer[i]; + if (inner == null || inner.length == 0) + continue; + wl.lock(); + try { + count--; + long ret = inner[inner.length - 1]; + outer[i] = Arrays_copyOf(inner, inner.length - 1); + return ret; + } finally { + wl.unlock(); + } + + } } + } finally { + rl.unlock(); } return 0; } - + public long[] keys() { int index = 0; - long ret[] = new long[count]; - for(long[][] outer : values) { - if(outer == null) continue; - for(long[] inner : outer) { - if(inner == null) continue; - for(long entry : inner) { - ret[index++] = entry; + rl.lock(); + try { + long ret[] = new long[count]; + for (long[][] outer : values) { + if (outer == null) + continue; + for (long[] inner : outer) { + if (inner == null) + continue; + for (long entry : inner) { + ret[index++] = entry; + } } } + return ret; + } finally { + rl.unlock(); } - return ret; } }
\ No newline at end of file |