/** * Establishes that the structure of the blocks is what it should be. * * @throws Error When the file is shorter than the fields in the file indicate. */ private void check() throws IOException { // Initial phase. // Check that the block file has the correct size. long nrValidBlocks = freeList.getNextItem(); long nrBlocks = getNrBlocks(); if (nrBlocks != nrValidBlocks) { if (nrBlocks < nrValidBlocks) { logger.error("File " + file + " may have been truncated."); throw new Error("File " + file + " may have been truncated."); } if (logger.isDebugEnabled()) { logger.debug("File " + file + " may not have been closed properly on shutdown.\n nrBlocks=" + nrBlocks + " nrValidBlocks=" + nrValidBlocks, new Throwable()); } blockFile.setNrBlocks(nrValidBlocks); } }
/** * Allocates a ByteBuffer to be used for writing to the specified block. The * contents of the ByteBuffer are undefined. The method {@link #writeBlock} * should be called to write the buffer to the block but, depending on the * BlockFile implementation, changes to the ByteBuffer may take effect even if * {@link #writeBlock} is never called. * * @param objectPool the object pool to attempt to get objects from and * release objects to. * @return a ByteBuffer to be used for writing to the specified block. * @throws IOException if an I/O error occurs. */ public Block allocateBlock(ObjectPool objectPool) throws IOException { assert this == currentPhase; long blockId = freeList.allocate(); blockFile.setNrBlocks(freeList.getNextItem()); Block block = blockFile.allocateBlock(objectPool, blockId); block.setBlockFile(this); return block; }
freeList != null && currentPhase != null ) { blockFile.setNrBlocks(freeList.getNextItem());
/** * Changes the block ID of the specified Block. This method is called * copyBlock because a call to copyBlock() followed by a call to * writeBlock() can be used to copy the contents of a block to a new * location in the block file. * * @param block the Block to be copied. * @param dstBlockId the ID of the block to which the Block will be written * when writeBlock() is called. * @throws IOException if an I/O error occurs. */ public void copyBlock(Block block, long dstBlockId) throws IOException { assert this == currentPhase; assert block.getBlockId() != dstBlockId; if (freeList.isSharedItem(dstBlockId)) { // Choose an alternative destination block since this one is shared // with another phase. freeList.free(dstBlockId); dstBlockId = freeList.allocate(); blockFile.setNrBlocks(freeList.getNextItem()); } blockFile.copyBlock(block, dstBlockId); }
/** * METHOD TO DO * * @param node PARAMETER TO DO * @throws NodePoolException EXCEPTION TO DO * @throws NoSuchNodeException EXCEPTION TO DO */ public synchronized void releaseNode( long node ) throws NodePoolException, NoSuchNodeException { checkInitialized(); try { if (node < MIN_NODE || node >= freeList.getNextItem()) { throw new NoSuchNodeException(node, "Invalid node ID: " + node); } freeList.free(node); } catch (NullPointerException ex) { throw new NodePoolException("Node pool not open."); } catch (IOException ex) { throw new NodePoolException("Failed to free node.", ex); } catch (IllegalStateException ex) { throw new NodePoolException("Node pool already initialized.", ex); } }
/** * Gets a new block from the file to write block data to. * The block data to write is a modified version of an existing block. * * @param block The block to be copied into the new "modified" block. * @throws IOException if an I/O error occurs. */ public void modifyBlock(Block block) throws IOException { assert this == currentPhase; if (freeList.isSharedItem(block.getBlockId())) { // Allocate a new block and copy block to it. long newBlockId = freeList.allocate(); blockFile.setNrBlocks(freeList.getNextItem()); // Although we use block after the block is freed, the block can't // be reused (by a later phase) until the current phase is committed. freeList.free(block.getBlockId()); blockFile.copyBlock(block, newBlockId); } }