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();