PhysicalRowId:A physical rowid is nothing else than a pointer to a physical location
in a file - a (block, offset) tuple.
里面有方法:
/** Returns the block number */
long getBlock() {
return block.readLong(pos + O_BLOCK);
}
/** Sets the block number */
void setBlock(long value) {
block.writeLong(pos + O_BLOCK, value);
}
还不是很明白这个block number和rowid是什么关系,好像这个number的设置是很自由的,奇怪
FreePhysicalRowId:This class extends the physical rowid with a size value to indicated
the size of a free rowid on the free rowid list.
这个类就是比PhysicalRowId多了一个size的设置,这个size是a free rowid的,不是很明白这句话,rowid需要这个size干吗?
FreePhysicalRowId id = ......
id.setBlock(1);
id.setOffset((short) 2);
id.setSize(3);
FreePhysicalRowIdPage:describe a page that holds physical rowids that were freed.
这个类管理rowid,其主要方法如下:
// slots we returned.
FreePhysicalRowId[] slots = new FreePhysicalRowId[ELEMS_PER_PAGE];
/** Returns the number of free rowids */
short getCount() {
return block.readShort(O_COUNT);
}
/** Sets the number of free rowids */
private void setCount(short i) {
block.writeShort(O_COUNT, i);
}
/** Frees a slot */
void free(int slot) {
get(slot).setSize(0);
setCount((short) (getCount() - 1));
}
/** Allocates a slot */
FreePhysicalRowId alloc(int slot) {
setCount((short) (getCount() + 1));
return get(slot);
}
/** Returns true if a slot is allocated */
boolean isAllocated(int slot) {
return get(slot).getSize() != 0;
}
/** Returns true if a slot is free */
boolean isFree(int slot) {
return !isAllocated(slot);
}
/** Returns the value of the indicated slot */
FreePhysicalRowId get(int slot) {
if (slots[slot] == null)
slots[slot] = new FreePhysicalRowId(block, slotToOffset(slot));;
return slots[slot];
}
/** Converts slot to offset */
short slotToOffset(int slot) {
return (short) (O_FREE +
(slot * FreePhysicalRowId.SIZE));
}
/**
* Returns first free slot, -1 if no slots are available
*/
int getFirstFree() {
for (int i = 0; i < ELEMS_PER_PAGE; i++) {
if (isFree(i))
return i;
}
return -1;
}
/**
* Returns first slot with available size >= indicated size,
* or -1 if no slots are available.
**/
int getFirstLargerThan(int size) {
for (int i = 0; i < ELEMS_PER_PAGE; i++) {
if (isAllocated(i) && get(i).getSize() >= size)
return i;
}
return -1;
}
以上主要是进行分配和释放工作,最后两个方法用于查找第一个free的slot和根据size查找slot,很有用,要记住。
在db中,一个库包含多个table,一个table包含多个记录。一个RecordFile应该就是一个db吧。
FreePhysicalRowIdPageManager:manages free physical rowid pages and provides methods
to free and allocate physical rowids on a high level.
它有两个成员变量:
// our record file
protected RecordFile _file;
// our page manager
protected PageManager _pageman;
RecordFile和PageManager这两个类前面都有研究,应该不是问题。FreePhysicalRowIdPageManager
只有两个方法:
/**
* Returns a free physical rowid of the indicated size, or
* null if nothing was found.
*/
Location get( int size )
/**
* Puts the indicated rowid on the free list
*/
void put(Location rowid, int size)
这里的get方法很重要,从这个方法里面可以看出数据文件的组织方式:
/**
* Returns a free physical rowid of the indicated size, or
* null if nothing was found.
*/
Location get( int size )
throws IOException
{
// Loop through the free physical rowid list until we find
// a rowid that's large enough.
Location retval = null;
PageCursor curs = new PageCursor( _pageman, Magic.FREEPHYSIDS_PAGE );
while (curs.next() != 0) {
FreePhysicalRowIdPage fp = FreePhysicalRowIdPage
.getFreePhysicalRowIdPageView( _file.get( curs.getCurrent() ) );
int slot = fp.getFirstLargerThan( size );
if ( slot != -1 ) {
// got one!
retval = new Location( fp.get( slot ) );
int slotsize = fp.get( slot ).getSize();
fp.free( slot );
if ( fp.getCount() == 0 ) {
// page became empty - free it
_file.release( curs.getCurrent(), false );
_pageman.free( Magic.FREEPHYSIDS_PAGE, curs.getCurrent() );
} else {
_file.release( curs.getCurrent(), true );
}
return retval;
} else {
// no luck, go to next page
_file.release( curs.getCurrent(), false );
}
}
return null;
}
当保存数据时,先得到FreePhysicalRowIdPage里面去查有没有合适大小的slot可用。得到合适的slot后,就得到了
FreePhysicalRowId。FreePhysicalRowId持有size信息,这个size前面没有搞清楚,到这里就清楚了,其实是可存放
数据文件的size。FreePhysicalRowId还持有BlockIo和offset信息,这个被Location使用,get方法最后也是返回Location对象。
PhysicalRowIdManager:manages physical row ids, and their data.