Skip to content

Instantly share code, notes, and snippets.

@socram8888
Last active August 29, 2015 14:09
Show Gist options
  • Save socram8888/3769ee88a0a54232b0dd to your computer and use it in GitHub Desktop.
Save socram8888/3769ee88a0a54232b0dd to your computer and use it in GitHub Desktop.
public class BlockAreaSet implements Set<Block> {
private final World world;
private final int baseX;
private final int baseY;
private final int baseZ;
private final int sizeX;
private final int sizeY;
private final int sizeZ;
private final int[] data;
private int count;
private int hashCode;
public BlockAreaSet(Block b1, Block b2) {
world = b1.getWorld();
if (!world.equals(b2.getWorld())) {
throw new IllegalArgumentException("Both blocks must be in the same world");
}
baseX = Math.min(b1.getX(), b2.getX());
baseY = Math.min(b1.getY(), b2.getY());
baseZ = Math.min(b1.getZ(), b2.getZ());
sizeX = Math.max(b1.getX(), b2.getX()) - baseX + 1;
sizeY = Math.max(b1.getY(), b2.getY()) - baseY + 1;
sizeZ = Math.max(b1.getZ(), b2.getZ()) - baseZ + 1;
initData();
}
public BlockAreaSet(Block center, int radius) {
world = center.getWorld();
baseX = center.getX() - radius;
baseY = center.getY() - radius;
baseZ = center.getZ() - radius;
sizeX = sizeY = sizeZ = 2 * radius;
initData();
}
private void initData() {
hashCode = (sizeX << 20 | sizeY << 16 | sizeZ) ^ baseX ^ baseY ^ baseZ;
data = new int[(sizeX * sizeY * sizeZ >>> 5) + 1];
}
private int calculateBitPos(Block block) {
if (!world.equals(block.getWorld())) {
throw new IllegalArgumentException("Block world is not valid");
}
int x = block.getX() - baseX;
int y = block.getY() - baseY;
int z = block.getZ() - baseZ;
if (x < 0 || x > sizeX || y < 0 || y > sizeY || z < 0 || z > sizeZ) {
throw new IllegalArgumentException("Block is outside the valid area");
}
return (z * sizeY + y) * sizeX + x;
}
@Override
public boolean contains(Object object) {
int pos;
try {
pos = calculateBitPos((Block) object);
} catch (IllegalArgumentException e) {
return false;
}
int index = pos >> 5;
int mask = 1 << (pos & 0x1F);
return (data[index] & mask) != 0;
}
@Override
public boolean add(Block block) {
pos = calculateBitPos(block);
int index = pos >> 5;
int mask = 1 << (pos & 0x1F);
if ((data[index] & mask) != 0) {
return false;
}
int v = data[index];
hashCode = hashCode ^ v ^ count;
v |= mask;
count++;
hashCode = hashCode ^ v ^ count;
data[index] = v;
return true;
}
@Override
public boolean addAll(Collection<? extends Block> blocks) {
boolean modified = false;
for (Block block : blocks) {
if (add(block)) {
modified = true;
}
}
return modified;
}
@Override
public void clear() {
count = 0;
Array.fill(data, 0);
}
@Override
public boolean containsAll(Collection<?> objects) {
for (Object object : objects) {
if (!contains(object)) {
return false;
}
}
return true;
}
@Override
public boolean equals(Object object) {
if (object == null) {
return false;
}
if (this == object) {
return true;
}
try {
Set set = (Set) object;
if (size() != set.size()) {
return false;
}
for (Object setObject : set) {
if (!contains(setObject)) {
return false;
}
}
return true;
} catch (Exception e) { }
return false;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean isEmpty() {
return count == 0;
}
@Override
public Iterator<Block> iterator() {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public boolean remove(Object obj) {
pos = calculateBitPos((Block) obj);
int index = pos >> 5;
int mask = 1 << (pos & 0x1F);
if ((data[index] & mask) == 0) {
return false;
}
int v = data[index];
hashCode = hashCode ^ v ^ count;
v &= ~mask;
count--;
hashCode = hashCode ^ v ^ count;
data[index] = v;
return true;
}
@Override
public boolean removeAll(Collection<?> objects) {
boolean modified = false;
for (Object object : objects) {
if (remove(object)) {
modified = true;
}
}
return modified;
}
@Override
public boolean retainAll(Collection<?> objects) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int size() {
return count;
}
@Override
public Object[] toArray() {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public <T> T[] toArray(T[] array) {
throw new UnsupportedOperationException("Not yet implemented");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment