1.record概念
Record是從使用者角度來說的,如使用PhysicalRowIdManager插入一個10000byte的Record
byte[] data = TestUtil.makeRecord(10000, (byte) 1);
Location loc = physMgr.insert( data, 0, data.length );
每一個記錄都會被DataPage和RecordHeader進行封裝:
curBlock = file.get( start );
curPage = DataPage.getDataPageView( curBlock );
curPage.setFirst( DataPage.O_DATA );
RecordHeader hdr = new RecordHeader( curBlock, DataPage.O_DATA );
hdr.setAvailableSize( 0 );
hdr.setCurrentSize( 0 );
一個BlockIo最多只能存儲8164(RecordFile.BLOCK_SIZE - DataPage.O_DATA - RecordHeader.SIZE)個bytes
如果不需要RecordHeader(這個BlockIo全都是data,不需要RecordHeader),那么可以存儲8172(RecordFile.BLOCK_SIZE - DataPage.O_DATA)個bytes。兩者相差RecordHeader.SIZE(8)個bytes。
curBlock = file.get( start );
curPage = DataPage.getDataPageView( curBlock );
curPage.setFirst( (short) 0 ); // no rowids, just data
上面最后一行代碼curPage.setFirst( (short) 0 )并不是說從0的位置開始可以存儲數據,而是從DataPage.O_DATA(20)開始存儲數據:
if ( leftToWrite > 0 ) {
block = file.get( curs.next() );
dataOffset = DataPage.O_DATA;
}
2.JDBM效率
順序插入記錄的時候,BlockIo能夠非常緊湊的使用,不會出現多余的空間遺漏,比如上面插入10000個bytes,那么第二次插入10000時,那么從第一次結束的地方開始(第二個BlockIo的offset為10000-8164+20=1856)安排第一個記錄。但是如果一旦出現update的情況則不一樣了,比如10000個bytes的記錄被update成20000個bytes,JDBM會釋放這個10000bytes的空間,在FREEPHYSIDS_PAGE中就多一個10000bytes的slot待使用。這個時候如果插入一個20bytes的記錄,那么就獨占這個10000bytes的空間,這就造成空間浪費。這種策略只適合查詢較多的情況,不適合頻繁的更新,當然可以優化,只從這個slot中取20+28個bytes空間,其他的依然放在這個slot中待使用。如果有時間,我想試試。