package org.voltdb.exceptions;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.voltdb.catalog.Database;
import org.voltdb.catalog.Table;
import edu.brown.hstore.HStoreConstants;
/**
* Special exception that is thrown by the EE when as transaction
* tries to access one or more tuples that have been evicted.
* This is used with the anti-cache feature.
*/
public class EvictedTupleAccessException extends SerializableException {
public static final long serialVersionUID = 0L;
public final int table_id;
public final int[] block_ids;
public final int[] tuple_offsets;
public int partition_id;
/**
*
* @param buffer ByteBuffer containing a serialized representation of the exception.
*/
public EvictedTupleAccessException(ByteBuffer buffer) {
super(buffer);
this.table_id = buffer.getInt();
final int num_blocks = buffer.getInt();
assert(num_blocks > 0) :
"Unexpected non-negative block count '" + num_blocks + "'";
this.block_ids = new int[num_blocks];
this.tuple_offsets = new int[num_blocks];
for (int i = 0; i < this.block_ids.length; i++) {
this.block_ids[i] = buffer.getInt();
} // FOR
for (int i = 0; i < this.tuple_offsets.length; i++) {
this.tuple_offsets[i] = buffer.getInt();
} // FOR
this.partition_id = buffer.getInt();
}
/**
* Retrieve the Table that the txn tried to access that generated this exception.
* @param catalog_db The current Database catalog handle
*/
public Table getTable(Database catalog_db) {
return catalog_db.getTables().values()[this.table_id-1];
}
/**
* Retrieve the block ids that the txn tried to access that generated this exception.
*/
public int[] getBlockIds() {
return (this.block_ids);
}
/**
* Retrieve the tuples ids that the txn tried to access that generated this exception.
*/
public int[] getTupleOffsets() {
return (this.tuple_offsets);
}
public int getPartitionId(){
return this.partition_id;
}
public void setPartitionId(int partition_id) {
assert(this.partition_id == HStoreConstants.NULL_PARTITION_ID) :
String.format("Trying to set %s.partition_id more than once [orig=%d / new=%d]",
EvictedTupleAccessException.class.getName(),
this.partition_id, partition_id);
this.partition_id = partition_id;
}
/**
* Return the amount of storage necessary to store this exception
*/
@Override
protected int p_getSerializedSize() {
// 4 bytes for tableId
// 2 bytes for # of block_ids
// (4 bytes * # of block_ids)
// (4 bytes * # of tuple offsets)
// 4 bytes for partition id
return (4 + 4 + (4 * this.block_ids.length) + (4 * this.tuple_offsets.length) + 4);
}
/**
* Write out the internal state information for this Exception
* @throws IOException
*/
@Override
protected void p_serializeToBuffer(ByteBuffer b) throws IOException {
b.putInt(this.table_id);
b.putInt(this.block_ids.length);
for (int i = 0; i < this.block_ids.length; i++) {
b.putInt(this.block_ids[i]);
} // FOR
for(int i = 0; i < this.tuple_offsets.length; i++) {
b.putInt(this.tuple_offsets[i]);
}
b.putInt(this.partition_id);
}
@Override
protected SerializableExceptions getExceptionType() {
return SerializableExceptions.EvictedTupleAccessException;
}
}