public class BufferAccess{
public static final int cacheSize= 16*1024*1024/DiskManagement.BLOCK_SIZE;
private static BufferAccess bufferAccessInstance= null;
private DiskManagement diskManagement;
/**
* 锁住的关键块,只在文件打开时放入,文件关闭时取出
* 存放mata, schema, index block, index info block
*/
private Set LockedBlockSet = new HashSet();
/**
* 块缓冲池,load factor 0.75,确保没有rehash发生
* 方便起见,只存DataBlock
*/
private Map blockCache=new HashMap((int)(cacheSize/0.75));
/**
* 时钟算法的环中的当前元素,下一个元素才是淘汰候选对象
*/
private DataBlock lastUsedBlock;
//stop here , review the clock algo and LRU algo
private BufferAccess(){
this.diskManagement = DiskManagement.getInstance();
}
public static BufferAccess getInstance() {
if(bufferAccessInstance == null)
bufferAccessInstance = new BufferAccess();
return bufferAccessInstance;
}
/**
* 从buffer中得到一个数据块
* @param fileID
* @param blockID
* @return
*/
public DataBlock getBlock (Integer fileID, int blockID){
IDEntry id =new IDEntry (fileID,blockID);
DataBlock block =(DataBlock) blockCache.get(id);
if(block !=null){
block.keepNextTurn=true;
return block;
}
byte[] blockByte=diskManagement.readFromDisk(fileID,blockID);
block =new DataBlock(blockByte,id);
ensureSpace();
addBlock(block);
blockCache.put(id,block);
return block;
}
void reloadDataBlock(DataBlock nullBlock){
IDEntry id=nullBlock.getIdEntry();
DataBlock block =(DataBlock) blockCache.get(id);
//内存中没有相同id的块
if(block ==null)
{
byte[] blockByte=diskManagement.readFromDisk(id.getFileID(),id.getBlockID());
ensureSpace();
nullBlock.setData(blockByte);
addBlock(nullBlock);
blockCache.put(id,nullBlock);
return;
}
//内存中有相同id的块,需要用到identical指针
nullBlock.setData(block.getData());
nullBlock.identical=block.identical;
block.identical = nullBock;
}
/**
* 得到一个锁住的块,该块不参与LRU算法的竞争
* 只可能是MetaBlock,SchemaBlock,IndexBlock
* @param fileID
* @param blockID
* @param blockType
* @return
*/
public Block getLockedBlock(Integer fileID, int blockID, int blockType) {
IDEntry id = new IDEntry(fileID, blockID);
Block block = null;
byte[] blockByte = diskManagement.readFromDisk(fileID, blockID);
switch(blockType){
case Block.META_BLOCK:
block= new MetaBlock(blockByte,id);
break;
case Block.SCHEMA_BLOCK:
block = new SchemaBlock(blockByte,id);
break;
case Block.INDEX_BLOCK:
block = new IndexBlock( blockByte, id );
break;
case Block.INDEX_INFO_BLOCK:
block = new IndexInfoBlock( blockByte, id);
break;
default:
System.out.println(" illegal block type argument ");
}
LockBlockSet.add(block);s