@Override public boolean compareAndSetBlock( int x, int y, int z, short expectId, short expectData, short newId, short newData) { int exp = BlockFullState.getPacked(expectId, expectData); int update = BlockFullState.getPacked(newId, newData); boolean success = store.compareAndSet(getIndex(x, y, z), exp, update); if (success && exp != update) { markDirty(x, y, z, exp, update); } return success; }
/** * Atomically gets the full set of data associated with the block.<br> * <br> * * @param x the x coordinate * @param y the y coordinate * @param z the z coordinate * @return the full state of the block */ @Override public int getFullData(int x, int y, int z) { int index = getIndex(x, y, z); int spins = 0; boolean interrupted = false; try { while (true) { if (spins++ > SPINS) { interrupted |= atomicWait(index); } checkCompressing(); int seq = getSequence(x, y, z); short blockId = blockIds.get(index); if (auxStore.isReserved(blockId)) { int state = auxStore.getInt(blockId); if (testSequence(x, y, z, seq)) { return state; } } else { int state = BlockFullState.getPacked(blockId, (short) 0); return state; } } } finally { if (interrupted) { Thread.currentThread().interrupt(); } } }
@Override public short[] getDataArray(short[] array) { if (array.length != length) { array = new short[length]; } for (int i = 0; i < length; i++) { array[i] = BlockFullState.getData(store.get(i)); } return array; }
@Override public int getAndSetBlock(int x, int y, int z, short id, short data) { int oldState = BlockFullState.getPacked(id, data); int newState = 0; try { return newState = store.set(getIndex(x, y, z), oldState); } finally { markDirty(x, y, z, oldState, newState); } }
public AtomicPaletteBlockStore( int shift, boolean storeState, int dirtySize, short[] blocks, short[] data) { this(shift, storeState, dirtySize); if (blocks != null) { int[] initial = new int[Math.min(blocks.length, this.length)]; for (int i = 0; i < blocks.length; i++) { short d = data != null ? data[i] : 0; initial[i] = BlockFullState.getPacked(blocks[i], d); } store.set(initial); } }
private int getAndSetBlockRaw(int x, int y, int z, short id, short data) { int index = getIndex(x, y, z); int spins = 0; boolean interrupted = false; try { while (true) { if (spins++ > SPINS) { interrupted |= atomicWait(index); } checkCompressing(); short oldBlockId = blockIds.get(index); boolean oldReserved = auxStore.isReserved(oldBlockId); if (data == 0 && !auxStore.isReserved(id)) { if (!blockIds.compareAndSet(index, oldBlockId, id)) { continue; } } else { int newIndex = auxStore.add(id, data); if (!blockIds.compareAndSet(index, oldBlockId, (short) newIndex)) { auxStore.remove(newIndex); continue; } } if (oldReserved) { return auxStore.remove(oldBlockId); } return BlockFullState.getPacked(oldBlockId, (short) 0); } } finally { markDirty(x, y, z); atomicNotify(index); if (interrupted) { Thread.currentThread().interrupt(); } } }
@Override public int getData(int x, int y, int z) { return BlockFullState.getData(getFullData(x, y, z)); }