Block block = blockFile.readBlock(objectPool, nextBlockId); if ( (prevBlockId >= 0) && (block.getInt(IDX_PREV) != prevBlockId)) { " Fixed." ); block.putInt(IDX_PREV, prevBlockId); block.write(); nextBlockId = block.getInt(IDX_NEXT); block.release(); } while (nextBlockId != 0); if (block.getInt(IDX_PREV) != prevBlockId) { block.putInt(IDX_PREV, prevBlockId); block.write(); block.release();
/** * Allocates a new block for dstBlockId, copies the contents of srcBlock to * it, releases srcBlock and returns the new Block. * * @param block The block to copy data from. This block will be set to the * destination block before returning, and acts as the return value. * @param dstBlockId the ID of the new Block to be allocated. */ public void copyBlock(Block block, long dstBlockId) { assert(block.getBlockId() >= 0) && (block.getBlockId() < nrBlocks); assert(dstBlockId >= 0) && (dstBlockId < nrBlocks); assert block.getBlockId() != dstBlockId; int byteOffset = block.getByteOffset(); ByteBuffer srcBuffer = block.getSourceBuffer(); srcBuffer.limit(byteOffset + blockSize); srcBuffer.position(byteOffset); long dstFileOffset = dstBlockId * blockSize; int dstRegionNr = (int) (dstFileOffset / stride); int dstByteOffset = (int) (dstFileOffset % stride); ByteBuffer dstBuffer = mappedByteBuffers[dstRegionNr]; dstBuffer.position(dstByteOffset); // Copy the bytes. dstBuffer.put(srcBuffer); block.init( dstBlockId, dstByteOffset, dstBuffer, srcByteBuffers[dstRegionNr], intBuffers[dstRegionNr], longBuffers[dstRegionNr] ); }
/** * Copies bytes from this block to the specified block. Only the write * session should call this method. * * @param offset Offset of the data to get. * @param block The data block to fill. */ public void get(int offset, Block block) { block.put(0, this, offset, block.blockSize); }
headBlock.putLong(offset, item); headBlockDirty = true; int nextHeadBlockId = headBlock.getInt(IDX_NEXT); blockFile.setNrBlocks(nextBlockId); allocateHeadBlock(newHeadBlockId); headBlock.putInt(IDX_NEXT, nextHeadBlockId); headBlock.putInt(IDX_PREV, (int) prevHeadBlock.getBlockId()); headBlockDirty = true; force(); prevHeadBlock.putInt(IDX_NEXT, newHeadBlockId); prevHeadBlock.write(); prevHeadBlock.release(); nextHeadBlock.putInt(IDX_PREV, newHeadBlockId); nextHeadBlock.write(); nextHeadBlock.release();
metarootBlocks[0].putInt(IDX_MAGIC, FILE_MAGIC); metarootBlocks[0].putInt(IDX_VERSION, FILE_VERSION); metarootBlocks[0].putInt(IDX_VALID, 0); metarootBlocks[0].write(); metarootBlocks[1].putInt(IDX_MAGIC, 0); metarootBlocks[1].putInt(IDX_VERSION, 0); metarootBlocks[1].putInt(IDX_VALID, 0); metarootBlocks[1].write(); metarootFile.force();
metarootBlocks[0].getInt(IDX_VALID) != 0 && metarootBlocks[0].getInt(IDX_PHASE_NUMBER) == phaseNumber ) { phaseIndex = 0; metarootBlocks[1].getInt(IDX_VALID) != 0 && metarootBlocks[1].getInt(IDX_PHASE_NUMBER) == phaseNumber ) { phaseIndex = 1; block.putInt(IDX_VALID, 0); block.write(); metarootFile.force();
avlNode.getBlock().put( (AVLNode.HEADER_SIZE + IDX_DATA) * Constants.SIZEOF_LONG, data ); Block block = blockFilePhase.allocateBlock(objectPool); try { block.put(0, data); block.write(); blockId = block.getBlockId(); return blockId; } finally { block.release();
/** * Releases the current tail buffer. After releasing, the tail buffer is made * invalid. * */ private void releaseTailBlock() { if (tailBlock != null) { tailBlock.release(); tailBlock = null; } }
/** * Writes a buffer that was allocated by calling either {@link * #allocateBlock} or {@link #readBlock} to the specified block. The buffer * may only be written to the same block as was specified when the buffer was * allocated. * * @param block the buffer to write to the file. */ public void writeBlock(Block block) { assert(block.getBlockId() >= 0) && (block.getBlockId() < nrBlocks); // NO-OP - this is because mapped buffers are automatically written }
int blockId = reallocateBlock.getInt(IDX_PREV); reallocate = ( (blockId * BLOCK_SIZE) + BLOCK_SIZE) - 1; } else { item = reallocateBlock.getLong(offset); readHeadBlock(getBlockId(head)); int blockId = headBlock.getInt(IDX_PREV); head = ( ( (long) blockId * BLOCK_SIZE) + BLOCK_SIZE) - 1; } else { readHeadBlock(getBlockId(head)); long tItem = headBlock.getLong(getBlockOffset(head)); readReallocateBlock(getBlockId(reallocate)); reallocateBlock.putLong(getBlockOffset(reallocate), tItem); reallocateBlockDirty = true; item = tailBlock.getLong(offset); int blockId = tailBlock.getInt(IDX_NEXT); tail = ( (long) blockId * BLOCK_SIZE) + HEADER_SIZE;
/** * Puts an integer into the payload of this node. * * @param offset The offset into the payload, in ints. * @param i The value to put into the payload. */ public void putPayloadInt(int offset, int i) { assert dirty; assert offset > 0; block.putInt(IDX_PAYLOAD_I + offset, i); }
/** * Gets an integer from the AVLNode payload * * @param offset The offset into the payload * @return The requested integer value */ public int getPayloadInt(int offset) { assert offset > 0; return block.getInt(IDX_PAYLOAD_I + offset); }
/** * Writes the current reallocate buffer back to the block file. The write is * only done if the buffer is valid and is dirty. The dirty flag will be set * to false at the end of this operation. * * @throws IOException if an I/O error occurs. */ private void writeReallocateBlock() throws IOException { if ( (reallocateBlock != null) && reallocateBlockDirty) { reallocateBlock.write(); reallocateBlockDirty = false; } }
long id = block.getBlockId(); block.modify(); writable = true; dirty = true; long newId = block.getBlockId(); parentNode.block.putLong(childIndex, newId); } else { phase.setRootId(newId);
/** * Reads data from the specified block into the ByteBuffer starting at the * current position. The number of bytes read is the number of remaining * bytes in the ByteBuffer. */ private ByteBuffer retrieveRemainingBytes( ObjectPool objectPool, ByteBuffer data, long blockId ) throws IOException { int dataSize = data.remaining(); if (dataSize > 0) { // Determine the block file to use. int fileIndex = XAUtils.log2( (dataSize - 1) >> (LOG2_MIN_BLOCK_SIZE - 1) ); ManagedBlockFile.Phase blockFilePhase = blockFilePhases[fileIndex]; Block block = blockFilePhase.readBlock(objectPool, blockId); try { block.get(0, data); } finally { block.release(); } } return data; }
/** * Writes a buffer that was allocated by calling either {@link * #allocateBlock} or {@link #readBlock} to the specified block. The buffer * may only be written to the same block as was specified when the buffer was * allocated. * * @param block the buffer to write to the file. * @throws IOException if an I/O error occurs. */ public void writeBlock(Block block) throws IOException { long blockId = block.getBlockId(); assert(blockId >= 0) && (blockId < nrBlocks); ByteBuffer byteBuffer = block.getByteBuffer(); for (;;) { try { // Reset the position. byteBuffer.rewind(); // Write the buffer to the file. fc.write(byteBuffer, blockId * blockSize); break; } catch (ClosedChannelException ex) { // The Channel may have been inadvertently closed by another thread // being interrupted. Attempt to reopen the channel. if (!ensureOpen()) { throw ex; } // Loop back and retry the write. } } }
/** * Frees a buffer that was allocated by calling either {@link #allocateBlock} * or {@link #readBlock}. While calling this method is not strictly * necessary, it may improve performance. The buffer should not be used after * it has been freed. * * @param objectPool The object pool to return the data buffer to. * @param block the buffer to be freed. */ public void releaseBlock(ObjectPool objectPool, Block block) { block.dispose(objectPool); }
/** * Frees all resources from this node, and releases its reference. * This should be the last reference to the node. * * @throws IOException If an I/O error occurs. */ private void free() throws IOException { writable = false; dirty = false; block.free(); block = null; release(); }