/*
* Created on 2005-1-24
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package buffer;
import java.util.Arrays;
import recordmanagement.AttributeType;
import dataitem.BooleanItem;
import dataitem.CharItem;
import dataitem.DataItem;
import dataitem.DoubleItem;
import dataitem.IntegerItem;
import dataitem.LongItem;
import dataitem.StringItem;
import dataitem.TimeItem;
import diskaccess.DiskManagement;
/**
* @author zh
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class IndexBlock extends Block {
private static final int NOT_NULL_OFFSET = 1;
private static final int POINTER_OFFSET = 4;
private static final int KEY_NUMBER_OFFSET = 0;
private static final int LAST_POINTER_OFFSET = 2;
private static final int STARTING_OFFSET =
LAST_POINTER_OFFSET + POINTER_OFFSET;
/**
* 节点中key的个数
*/
private short keyNum;
/**
* 子节点地址
*/
private int[] pointerArray;
/**
* 键类型
*/
private AttributeType type;
/**
* 数据
*/
private DataItem[] keyArray;
/**
* @param buffer
* @param id
*/
IndexBlock(byte[] buffer, IDEntry id) {
super(buffer, id);
}
public void initialize(AttributeType type, boolean byExternal) {
if (initialized()) {
if (byExternal) {
throw new IllegalArgumentException("new block has an error");
}
return;
}
this.type = type;
int n = type.getIndexCapacity();
// 两个数组都加一,方便插入,实际上只能有n个指针,n-1个键
pointerArray = new int[n + 2];
keyArray = new DataItem[n + 1];
if (byExternal) {
setData(null);
keyNum = 0;
// 叶节点中最后一个顺序指针初始化
pointerArray[n + 1] = -1;
modified = true;
return;
}
keyNum = getShort(KEY_NUMBER_OFFSET);
pointerArray[n + 1] = getInt(LAST_POINTER_OFFSET);
int offset = STARTING_OFFSET;
for (int i = 0; i <= keyNum; i++) {
pointerArray[i] = getInt(offset);
offset += POINTER_OFFSET;
}
// 读入键
readKey(offset);
// 不需要如此大的空间了
setData(null);
}
private void readKey(int offset) {
int keyByteAndNullFlagLength =
type.getByteLength() + NOT_NULL_OFFSET;
switch (type.getType()) {
case AttributeType.BOOLEAN:
for (int i = 0; i < keyNum; i++) {
if (getBoolean(offset))
keyArray[i] = new BooleanItem(getBoolean(offset
+ NOT_NULL_OFFSET));
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.CHAR:
for (int i = 0; i < keyNum; i++) {
if (getBoolean(offset))
keyArray[i] = new CharItem(
getChar(offset + NOT_NULL_OFFSET));
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.INTEGER:
for (int i = 0; i < keyNum; i++) {
if (getBoolean(offset))
keyArray[i] = new IntegerItem(getInt(offset
+ NOT_NULL_OFFSET));
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.LONG:
for (int i = 0; i < keyNum; i++) {
if (getBoolean(offset))
keyArray[i] = new LongItem(
getLong(offset + NOT_NULL_OFFSET));
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.DOUBLE:
for (int i = 0; i < keyNum; i++) {
if (getBoolean(offset))
keyArray[i] = new DoubleItem(getDouble(offset
+ NOT_NULL_OFFSET));
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.TIME:
for (int i = 0; i < keyNum; i++) {
if (getBoolean(offset))
keyArray[i] = new TimeItem(
getTime(offset + NOT_NULL_OFFSET));
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.STRING:
for (int i = 0; i < keyNum; i++) {
if (getBoolean(offset))
keyArray[i] = new StringItem(getString(offset
+ NOT_NULL_OFFSET, keyByteAndNullFlagLength / 2));
offset += keyByteAndNullFlagLength;
}
break;
default:
System.out.println("illegal argument");
break;
}
}
protected void releaseMemory(DiskManagement disk) {
if (modified) {
int size = STARTING_OFFSET + (keyNum + 1) * POINTER_OFFSET + keyNum
* (type.getByteLength() + NOT_NULL_OFFSET);
byte[] dt = new byte[size];
setData(dt);
setShort(KEY_NUMBER_OFFSET, keyNum);
setInt(LAST_POINTER_OFFSET, pointerArray[pointerArray.length - 1]);
int offset = STARTING_OFFSET;
for (int i = 0; i <= keyNum; i++) {
setInt(offset, pointerArray[i]);
offset += POINTER_OFFSET;
}
writeKey(offset);
modified = false;
super.writeBlock(disk);
}
// 清空内存空间
pointerArray = null;
keyArray = null;
}
private void writeKey(int offset) {
int keyByteAndNullFlagLength =
type.getByteLength() + NOT_NULL_OFFSET;
switch (type.getType()) {
case AttributeType.BOOLEAN:
for (int i = 0; i < keyNum; i++) {
if (keyArray[i] != null) {
setBoolean(offset, true);
setBoolean(offset + NOT_NULL_OFFSET, ((BooleanItem)keyArray[i]).getData() );
}
else {
setBoolean(offset, false);
}
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.CHAR:
for (int i = 0; i < keyNum; i++) {
if (keyArray[i] != null) {
setBoolean(offset, true);
setChar(offset + NOT_NULL_OFFSET, ((CharItem)keyArray[i]).getData() );
}
else {
setBoolean(offset, false);
}
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.INTEGER:
for (int i = 0; i < keyNum; i++) {
if (keyArray[i] != null) {
setBoolean(offset, true);
setInt(offset + NOT_NULL_OFFSET, ((IntegerItem)keyArray[i]).getData() );
}
else {
setBoolean(offset, false);
}
offset += keyByteAndNullFlagLength;
}
break;
case AttributeType.LONG:
for (int i = 0; i < keyNum; i++) {
if (keyArray[i] != null) {
setBoolean(offset, true);
setLong(offset + NOT_NULL_OFFSET, ((LongItem)keyArray[i]).getData() );
}
else {
setBoolean(offset, false);
}
offset += keyByteAndNullFlagLength;
}
break;
评论7
最新资源