
jdbm.recman.BlockIo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apacheds-jdbm2 Show documentation
Show all versions of apacheds-jdbm2 Show documentation
Specific JDBM Implementation with MVCC
The newest version!
/**
* JDBM LICENSE v1.00
*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The name "JDBM" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of Cees de Groot. For written permission,
* please contact [email protected].
*
* 4. Products derived from this Software may not be called "JDBM"
* nor may "JDBM" appear in their names without prior written
* permission of Cees de Groot.
*
* 5. Due credit should be given to the JDBM Project
* (http://jdbm.sourceforge.net/).
*
* THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2000 (C) Cees de Groot. All Rights Reserved.
* Contributions are Copyright (C) 2000 by their associated contributors.
*
* $Id: BlockIo.java,v 1.2 2002/08/06 05:18:36 boisvert Exp $
*/
package jdbm.recman;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.concurrent.atomic.AtomicInteger;
import jdbm.I18n;
/**
* This class wraps a page-sized byte array and provides methods to read and
* write data to and from it. The readers and writers are just the ones that
* the rest of the toolkit needs, nothing else. Values written are compatible
* with java.io routines.
*
* This block is never accessed directly, so it does not have to be thread-safe.
*
* @see java.io.DataInput
* @see java.io.DataOutput
*/
public final class BlockIo implements java.io.Externalizable
{
public final static long serialVersionUID = 2L;
/** The block Identifier */
private long blockId;
/** The row data contained in this block */
private byte[] data;
/** A view on the BlockIo */
private BlockView view = null;
/** A flag set when this block has been modified */
private boolean dirty = false;
/** The number of pending transaction on this block */
private AtomicInteger transactionCount = new AtomicInteger( 0 );
/**
* Default constructor for serialization
*/
public BlockIo()
{
// empty
}
/**
* Constructs a new BlockIo instance.
*
* @param blockId The identifier for this block
* @param data The data to store
*/
/*No qualifier*/ BlockIo( long blockId, byte[] data )
{
// remove me for production version
if ( blockId < 0 )
{
throw new Error( I18n.err( I18n.ERR_539_BAD_BLOCK_ID, blockId ) );
}
this.blockId = blockId;
this.data = data;
}
/**
* @return the underlying array
*/
/*No qualifier*/ byte[] getData()
{
return data;
}
/**
* Sets the block number. Should only be called by RecordFile.
*
* @param The block identifier
*/
/*No qualifier*/ void setBlockId( long blockId )
{
if ( isInTransaction() )
{
throw new Error( I18n.err( I18n.ERR_540 ) );
}
if ( blockId < 0 )
{
throw new Error( I18n.err( I18n.ERR_539_BAD_BLOCK_ID, blockId ) );
}
this.blockId = blockId;
}
/**
* @return the block number.
*/
/*No qualifier*/ long getBlockId()
{
return blockId;
}
/**
* @return the current view of the block.
*/
public BlockView getView()
{
return view;
}
/**
* Sets the current view of the block.
*
* @param view the current view
*/
public void setView( BlockView view )
{
this.view = view;
}
/**
* Sets the dirty flag
*/
/*No qualifier*/ void setDirty()
{
dirty = true;
}
/**
* Clears the dirty flag
*/
/*No qualifier*/ void setClean()
{
dirty = false;
}
/**
* Returns true if the dirty flag is set.
*/
/*No qualifier*/ boolean isDirty()
{
return dirty;
}
/**
* Returns true if the block is still dirty with respect to the
* transaction log.
*/
/*No qualifier*/ boolean isInTransaction()
{
return transactionCount.get() != 0;
}
/**
* Increments transaction count for this block, to signal that this
* block is in the log but not yet in the data recordFile. The method also
* takes a snapshot so that the data may be modified in new transactions.
*/
/*No qualifier*/ void incrementTransactionCount()
{
transactionCount.getAndIncrement();
}
/**
* Decrements transaction count for this block, to signal that this
* block has been written from the log to the data recordFile.
*/
/*No qualifier*/ void decrementTransactionCount()
{
if ( transactionCount.decrementAndGet() < 0 )
{
throw new Error( I18n.err( I18n.ERR_541, getBlockId() ) );
}
}
/**
* Reads a byte from the indicated position
*
* @param pos the position at which we will read the byte
* @return the read byte
*/
public byte readByte( int pos )
{
return data[pos];
}
/**
* Writes a byte to the indicated position
*
* @param pos The position where we want to write the value to
* @param value the byte value we want to write into the BlockIo
*/
public void writeByte( int pos, byte value )
{
data[pos] = value;
dirty = true;
}
/**
* Reads a short from the indicated position
*
* @param pos the position at which we will read the short
* @return the read short
*/
public short readShort( int pos )
{
return ( short )
( ( ( data[pos+0] & 0xff ) << 8 ) |
( ( data[pos+1] & 0xff ) << 0 ) );
}
/**
* Writes a short to the indicated position
*
* @param pos The position where we want to write the value to
* @param value the short value we want to write into the BlockIo
*/
public void writeShort( int pos, short value )
{
data[pos+0] = ( byte ) ( 0xff & ( value >> 8 ) );
data[pos+1] = ( byte ) ( 0xff & ( value >> 0 ) );
dirty = true;
}
/**
* Reads an int from the indicated position
*
* @param pos the position at which we will read the int
* @return the read int
*/
public int readInt( int pos )
{
return
( data[pos+0] << 24) |
( ( data[pos+1] & 0xff ) << 16) |
( ( data[pos+2] & 0xff ) << 8) |
( ( data[pos+3] & 0xff ) << 0 );
}
/**
* Writes an int to the indicated position
*
* @param pos The position where we want to write the value to
* @param value the int value we want to write into the BlockIo
*/
public void writeInt( int pos, int value )
{
data[pos+0] = ( byte ) ( 0xff & ( value >> 24 ) );
data[pos+1] = ( byte ) ( 0xff & ( value >> 16 ) );
data[pos+2] = ( byte ) ( 0xff & ( value >> 8 ) );
data[pos+3] = ( byte ) ( 0xff & ( value >> 0 ) );
dirty = true;
}
/**
* Reads a long from the indicated position
*
* @param pos the position at which we will read the long
* @return the read long
*/
public long readLong( int pos )
{
return
( ( (long)data[pos+0] << 56 ) |
( (long)( data[pos+1] & 0xff ) << 48 ) |
( (long)( data[pos+2] & 0xff ) << 40 ) |
( (long)( data[pos+3] & 0xff ) << 32 ) |
( (long)( data[pos+4] & 0xff ) << 24 ) |
( (long)( data[pos+5] & 0xff ) << 16 ) |
( (long)( data[pos+6] & 0xff ) << 8 ) |
( data[pos+7] & 0xff ) );
}
/**
* Writes a long to the indicated position
*
* @param pos The position where we want to write the value to
* @param value the long value we want to write into the BlockIo
*/
public void writeLong(int pos, long value) {
data[pos+0] = (byte)(0xff & (value >> 56));
data[pos+1] = (byte)(0xff & (value >> 48));
data[pos+2] = (byte)(0xff & (value >> 40));
data[pos+3] = (byte)(0xff & (value >> 32));
data[pos+4] = (byte)(0xff & (value >> 24));
data[pos+5] = (byte)(0xff & (value >> 16));
data[pos+6] = (byte)(0xff & (value >> 8));
data[pos+7] = (byte)(0xff & (value >> 0));
dirty = true;
}
/**
* {@inheritDoc}
*/
public String toString()
{
if ( view != null )
{
return view.toString();
}
StringBuilder sb = new StringBuilder();
sb.append( "BlockIO ( " );
// The blockID
sb.append( blockId ).append( ", " );
// Is it dirty ?
if ( dirty )
{
sb.append( "dirty, " );
}
else
{
sb.append( "clean, " );
}
// The view
if ( view != null )
{
sb.append( view.getClass().getSimpleName() ).append( ", " );
}
else
{
sb.append( "no view, " );
}
// The transaction count
sb.append( "tx: " ).append( transactionCount.get() );
sb.append( " )" );
return sb.toString();
}
/**
* implement externalizable interface
*/
public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
{
blockId = in.readLong();
int length = in.readInt();
data = new byte[length];
in.readFully(data);
}
/**
* implement externalizable interface
*/
public void writeExternal( ObjectOutput out ) throws IOException
{
out.writeLong( blockId );
out.writeInt( data.length );
out.write( data );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy