1.PageHeader
PageManager有一個成員變量FileHeader,FileHeader represents a file header. It is a 1:1 representation of the data
that appears in block 0 of a file.FileHeader主要是存儲了一些數值:offset和blockid。這些數值是用一個也是RecordFile的第一個BLockIo對象進行存儲的,所以它有一個BlockIo的引用。
先看其成員變量:
    // offsets
    private static final short O_MAGIC = 0; // short magic
    private static final short O_LISTS = Magic.SZ_SHORT; // long[2*NLISTS]
    private static final int O_ROOTS =
        O_LISTS + (Magic.NLISTS * 2 * Magic.SZ_LONG);

    // my block
    private BlockIo block;

O_MAGIC表示FileHeader標示的位置:block.writeShort(O_MAGIC, Magic.FILE_HEADER)向0的位置寫入
FileHeader的文件頭。

O_LISTS標示LISTS的offset的位置,顯然前面是short類型的變量,所以O_LISTS = Magic.SZ_SHORT
O_ROOTS = O_LISTS + (Magic.NLISTS * 2 * Magic.SZ_LONG) Magic.NLISTS等于5,即五個List:
 short FREE_PAGE = 0;
 short USED_PAGE = 1;
 short TRANSLATION_PAGE = 2;
 short FREELOGIDS_PAGE = 3;
 short FREEPHYSIDS_PAGE = 4;
乘2則表示每隔List需要使用2個Magic.SZ_LONG長度,FIleHeader使用2個Magic.SZ_LONG長度的來記錄當前list
中第一個和最后一個block的offset:
     /**
     *  Returns the first block of the indicated list
     */
    long getFirstOf(int list) {
        return block.readLong(offsetOfFirst(list));
    }
   
    /**
     *  Sets the first block of the indicated list
     */
    void setFirstOf(int list, long value) {
        block.writeLong(offsetOfFirst(list), value);
    }
    上面的getFirstOf和setFirstOf中輸入的參數int list是0~4的值,即上面的5中list的類型值
    即getFirstOf和setFirstOf式獲取和設置相應list第一個block順序號的大小
    而下面是設置最后一個block順序號的大小。
   
     /**
     *  Returns the last block of the indicated list
     */
    long getLastOf(int list) {
        return block.readLong(offsetOfLast(list));
    }
   
    /**
     *  Sets the last block of the indicated list
     */
    void setLastOf(int list, long value) {
        block.writeLong(offsetOfLast(list), value);
    }
   
    /** Returns the offset of the "first" block of the indicated list */
    private short offsetOfFirst(int list) {
        return (short) (O_LISTS + (2 * Magic.SZ_LONG * list));
    }

    /** Returns the offset of the "last" block of the indicated list */
    private short offsetOfLast(int list) {
        return (short) (offsetOfFirst(list) + Magic.SZ_LONG);
    }


2.PageManager
PageManager管理5個LinkedList,每一個type有一個LinkedList,LinkedList里面的元素就是BlockIo對象。這些LinkedList構成了
RecordFile對象。一個PageManager只有一個FileHeader。

 

    // our record file
    private RecordFile file;
    // header data
    private FileHeader header;
    private BlockIo headerBuf;
   
    /**
     *  Creates a new page manager using the indicated record file.
     */
    PageManager(RecordFile file) throws IOException {
        this.file = file;
       
        // check the file header. If the magic is 0, we assume a new
        // file. Note that we hold on to the file header node.
        headerBuf = file.get(0);
        if (headerBuf.readShort(0) == 0)
            header = new FileHeader(headerBuf, true);
        else
            header = new FileHeader(headerBuf, false);
    }

PageHeader對BlockIo進行了封裝,也就是說LinkedList里面元素實際上市PageHeader對象。但是這是為什么呢?
這個PageHeader主要是做什么的?而且這寫是怎么關聯起來的呢?下面在PageManager的allocate方法有幾行代碼
可能幫助理解:
 buf = file.get(oldLast);
 pageHdr = PageHeader.getView(buf);
 pageHdr.setNext(retval);
 file.release(oldLast, true);
每一個BlockIo都需要一個PageHeader,這點我真是不大理解,PageHeader,這個Page到底是什么?難道
每一個BlockIo都是一個Page?PageHeader的主要方法就是設置next和previous:

    /** Returns the next block. */
    long getNext() {
        paranoiaMagicOk();
        return block.readLong(O_NEXT);
    }
   
    /** Sets the next block. */
    void setNext(long next) {
        paranoiaMagicOk();
        block.writeLong(O_NEXT, next);
    }
   
    /** Returns the previous block. */
    long getPrev() {
        paranoiaMagicOk();
        return block.readLong(O_PREV);
    }
   
    /** Sets the previous block. */
    void setPrev(long prev) {
        paranoiaMagicOk();
        block.writeLong(O_PREV, prev);
    }

next和previous的id放在O_NEXT和O_PREV的位置。


3.PageHeader的作用

PageHeader類構造函數有一個參數BlockIo block,注釋應為@param block The block that contains the page header
而不是@param block The block that contains the file header。

這基本可以確定,每一個BLockIo都有一個PageHeader,這些PageHeader構成一個LinkedList。
那么怎么得到這些LinkedList里面的對象呢?看一下PageManager這些方法就知道了:
    /**
     *  Returns the page following the indicated block
     */
    long getNext(long block) throws IOException {
        try {
            return PageHeader.getView(file.get(block)).getNext();
        } finally {
            file.release(block, false);
        }
    }
   
    /**
     *  Returns the page before the indicated block
     */
    long getPrev(long block) throws IOException {
        try {
            return PageHeader.getView(file.get(block)).getPrev();
        } finally {
            file.release(block, false);
        }
    }
   
    /**
     *  Returns the first page on the indicated list.
     */
    long getFirst(short type) throws IOException {
        return header.getFirstOf(type);
    }

    /**
     *  Returns the last page on the indicated list.
     */
    long getLast(short type) throws IOException {
        return header.getLastOf(type);
    }
   
其實一般不會這么直接獲取,而是通過如下的代碼進行的:
 RecordFile f = new RecordFile(TestRecordFile.testFileName);
        pm = new PageManager(f);
        PageCursor curs = new PageCursor(pm, Magic.USED_PAGE);
        long i = 1;
        while (true) {
            long cur = curs.next();
            if (cur == 0)
           break;
            //對cur進行操作
        }
        pm.close();
        f.close();