9595 */
9696public abstract class AbstractPagedFileHeader implements PagedFileHeader {
9797 //<editor-fold desc="Description of the file header format">
98- private static final int LENGTH_VERSION_ID = 2 ; //sizeof short
99- private static final int LENGTH_HEADER_SIZE = 2 ; //sizeof short
100- private static final int LENGTH_PAGE_COUNT = 8 ; //sizeof long
101- private static final int LENGTH_PAGE_SIZE = 4 ; //sizeof int
102- private static final int LENGTH_TOTAL_COUNT = 8 ; //sizeof long
103- private static final int LENGTH_FIRST_FREE_PAGE = 8 ; //sizeof long
104- private static final int LENGTH_LAST_FREE_PAGE = 8 ; //sizeof long
105- private static final int LENGTH_PAGE_HEADER_SIZE = 1 ; //sizeof byte
106- private static final int LENGTH_MAX_KEY_SIZE = 2 ; //sizeof short
107- private static final int LENGTH_RECORD_COUNT = 8 ; //sizeof long
108-
109- private static final int OFFSET_VERSION_ID = 0 ;
110- private static final int OFFSET_HEADER_SIZE = OFFSET_VERSION_ID + LENGTH_VERSION_ID ; //2
111- private static final int OFFSET_PAGE_SIZE = OFFSET_HEADER_SIZE + LENGTH_HEADER_SIZE ; //4
112- private static final int OFFSET_PAGE_COUNT = OFFSET_PAGE_SIZE + LENGTH_PAGE_SIZE ; //8
113- private static final int OFFSET_TOTAL_COUNT = OFFSET_PAGE_COUNT + LENGTH_PAGE_COUNT ; //16
114- private static final int OFFSET_FIRST_FREE_PAGE = OFFSET_TOTAL_COUNT + LENGTH_TOTAL_COUNT ; //24
115- private static final int OFFSET_LAST_FREE_PAGE = OFFSET_FIRST_FREE_PAGE + LENGTH_FIRST_FREE_PAGE ; //32
116- private static final int OFFSET_PAGE_HEADER_SIZE = OFFSET_LAST_FREE_PAGE + LENGTH_LAST_FREE_PAGE ; //40
117- private static final int OFFSET_MAX_KEY_SIZE = OFFSET_PAGE_HEADER_SIZE + LENGTH_PAGE_HEADER_SIZE ; //41
118- private static final int OFFSET_RECORD_COUNT = OFFSET_MAX_KEY_SIZE + LENGTH_MAX_KEY_SIZE ; //43
119- private static final int OFFSET_REMAINDER = OFFSET_RECORD_COUNT + LENGTH_RECORD_COUNT ; //51
98+ private static final int LENGTH_VERSION_ID = 2 ; // sizeof(short)
99+ private static final int LENGTH_HEADER_SIZE = 2 ; // sizeof(short)
100+ private static final int LENGTH_PAGE_COUNT = 8 ; // sizeof(long)
101+ private static final int LENGTH_PAGE_SIZE = 4 ; // sizeof(int)
102+ private static final int LENGTH_TOTAL_COUNT = 8 ; // sizeof(long)
103+ private static final int LENGTH_FIRST_FREE_PAGE = 8 ; // sizeof(long)
104+ private static final int LENGTH_LAST_FREE_PAGE = 8 ; // sizeof(long)
105+ private static final int LENGTH_PAGE_HEADER_SIZE = 1 ; // sizeof(byte)
106+ private static final int LENGTH_MAX_KEY_SIZE = 2 ; // sizeof(short)
107+ protected static final int LENGTH_RECORD_COUNT = 8 ; // sizeof(long)
108+
109+ private static final int OFFSET_VERSION_ID = 0 ; // 0
110+ private static final int OFFSET_HEADER_SIZE = OFFSET_VERSION_ID + LENGTH_VERSION_ID ; // 2
111+ private static final int OFFSET_PAGE_SIZE = OFFSET_HEADER_SIZE + LENGTH_HEADER_SIZE ; // 4
112+ private static final int OFFSET_PAGE_COUNT = OFFSET_PAGE_SIZE + LENGTH_PAGE_SIZE ; // 8
113+ private static final int OFFSET_TOTAL_COUNT = OFFSET_PAGE_COUNT + LENGTH_PAGE_COUNT ; // 16
114+ private static final int OFFSET_FIRST_FREE_PAGE = OFFSET_TOTAL_COUNT + LENGTH_TOTAL_COUNT ; // 24
115+ private static final int OFFSET_LAST_FREE_PAGE = OFFSET_FIRST_FREE_PAGE + LENGTH_FIRST_FREE_PAGE ; // 32
116+ private static final int OFFSET_PAGE_HEADER_SIZE = OFFSET_LAST_FREE_PAGE + LENGTH_LAST_FREE_PAGE ; // 40
117+ private static final int OFFSET_MAX_KEY_SIZE = OFFSET_PAGE_HEADER_SIZE + LENGTH_PAGE_HEADER_SIZE ; // 41
118+ protected static final int OFFSET_RECORD_COUNT = OFFSET_MAX_KEY_SIZE + LENGTH_MAX_KEY_SIZE ; // 43
120119 //</editor-fold>
121120
122121 private final static byte DEFAULT_PAGE_HEADER_SIZE = 64 ;
123122 private final static short DEFAULT_MAX_KEY_SIZE = 256 ;
124123
125124 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock ();
126125
127- private short version ; // TODO(AR) try and make final?
128- private short headerSize ; // TODO(AR) try and make final?
129- private int pageSize ; // TODO(AR) try and make final?
126+ //<editor-fold desc="Immutable state">
127+ private final short version ;
128+ private final short headerSize ;
129+ private final int pageSize ;
130+ private final byte pageHeaderSize ;
131+ private final short maxKeySize ;
132+ private final int workSize ;
133+
134+ /**
135+ * This is here so that we can allocate once and reuse multiple times in {@link #write(byte[])}.
136+ */
137+ private final byte [] headerBuf ;
138+ // </editor-fold>
139+
140+ //<editor-fold desc="Mutable state">
130141 private long totalCount ;
131- private long firstFreePage = Page .NO_PAGE ;
132- private long lastFreePage = Page .NO_PAGE ;
133- private byte pageHeaderSize = DEFAULT_PAGE_HEADER_SIZE ; // TODO(AR) try and make final?
134- private short maxKeySize = DEFAULT_MAX_KEY_SIZE ; // TODO(AR) try and make final?
135-
136- private final byte [] buf ;
137- private int workSize ; // TODO(AR) try and make final, i.e. calculate once and then we don't need to re-calc ?
138- private boolean dirty = false ;
139-
140- public AbstractPagedFileHeader (final short fileVersion , final long pageCount , final int pageSize ) {
141- this .version = fileVersion ;
142- this .headerSize = (short ) pageSize ;
142+ private long firstFreePage ;
143+ private long lastFreePage ;
144+ private boolean dirty ;
145+ //</editor-fold>
146+
147+ protected AbstractPagedFileHeader (final short version , final short headerSize , final int pageSize , final byte pageHeaderSize , final short maxKeySize , final long firstFreePage , final long lastFreePage , final long totalCount ) {
148+ this .version = version ;
149+ this .headerSize = headerSize ;
143150 this .pageSize = pageSize ;
144- this .totalCount = pageCount ;
145- this .buf = new byte [this .headerSize ];
146- this .workSize = calculateWorkSize ();
151+ this .pageHeaderSize = pageHeaderSize ;
152+ this .maxKeySize = maxKeySize ;
153+ this .firstFreePage = firstFreePage ;
154+ this .lastFreePage = lastFreePage ;
155+ this .totalCount = totalCount ;
156+ this .workSize = this .pageSize - this .pageHeaderSize ;
157+ this .headerBuf = new byte [headerSize ];
147158 }
148159
149- // TODO(AR) remove this and try and inline it
150- private int calculateWorkSize () {
151- return this .pageSize - this .pageHeaderSize ;
160+ protected AbstractPagedFileHeader (final short version , final long pageCount , final int pageSize ) {
161+ this (version , (short ) pageSize , pageSize , DEFAULT_PAGE_HEADER_SIZE , DEFAULT_MAX_KEY_SIZE , Page .NO_PAGE , Page .NO_PAGE , pageCount );
152162 }
153163
154164 /**
@@ -280,28 +290,21 @@ public void setDirty(final boolean dirty) {
280290 this .dirty = dirty ;
281291 }
282292
283- public void read (final RandomAccessFile raf ) throws IOException {
284- raf .seek (0 );
285- raf .read (this .buf );
286- read (this .buf );
287- this .workSize = calculateWorkSize ();
288- this .dirty = false ;
289- }
290-
291- protected int read (final byte [] buf ) throws IOException {
292- this .version = ByteConversion .byteToShort (buf , OFFSET_VERSION_ID );
293- this .headerSize = ByteConversion .byteToShort (buf , OFFSET_HEADER_SIZE );
294- this .pageSize = ByteConversion .byteToInt (buf , OFFSET_PAGE_SIZE );
293+ protected static AbstractPagedFileHeaderData readAbstractPagedFileHeaderData (final byte [] headerBuf ) {
294+ final short version = ByteConversion .byteToShort (headerBuf , OFFSET_VERSION_ID );
295+ final short headerSize = ByteConversion .byteToShort (headerBuf , OFFSET_HEADER_SIZE );
296+ final int pageSize = ByteConversion .byteToInt (headerBuf , OFFSET_PAGE_SIZE );
295297 // NOTE(AR) pageCount no longer seems to be needed
296- // this. pageCount = ByteConversion.byteToLong(buf, OFFSET_PAGE_COUNT);
297- this . totalCount = ByteConversion .byteToLong (buf , OFFSET_TOTAL_COUNT );
298- this . firstFreePage = ByteConversion .byteToLong (buf , OFFSET_FIRST_FREE_PAGE );
299- this . lastFreePage = ByteConversion .byteToLong (buf , OFFSET_LAST_FREE_PAGE );
300- this . pageHeaderSize = buf [OFFSET_PAGE_HEADER_SIZE ];
301- this . maxKeySize = ByteConversion .byteToShort (buf , OFFSET_MAX_KEY_SIZE );
298+ // final long pageCount = ByteConversion.byteToLong(buf, OFFSET_PAGE_COUNT);
299+ final long totalCount = ByteConversion .byteToLong (headerBuf , OFFSET_TOTAL_COUNT );
300+ final long firstFreePage = ByteConversion .byteToLong (headerBuf , OFFSET_FIRST_FREE_PAGE );
301+ final long lastFreePage = ByteConversion .byteToLong (headerBuf , OFFSET_LAST_FREE_PAGE );
302+ final byte pageHeaderSize = headerBuf [OFFSET_PAGE_HEADER_SIZE ];
303+ final short maxKeySize = ByteConversion .byteToShort (headerBuf , OFFSET_MAX_KEY_SIZE );
302304 // NOTE(AR) recordCount no longer seems to be needed
303- // this.recordCount = ByteConversion.byteToLong(buf, OFFSET_RECORD_COUNT);
304- return OFFSET_REMAINDER ;
305+ // final long recordCount = ByteConversion.byteToLong(buf, OFFSET_RECORD_COUNT);
306+
307+ return new AbstractPagedFileHeaderData (version , headerSize , pageSize , totalCount , firstFreePage , lastFreePage , pageHeaderSize , maxKeySize );
305308 }
306309
307310 protected int write (final byte [] buf ) throws IOException {
@@ -317,13 +320,13 @@ protected int write(final byte[] buf) throws IOException {
317320 ByteConversion .shortToByte (this .maxKeySize , buf , OFFSET_MAX_KEY_SIZE );
318321 // NOTE(AR) recordCount no longer seems to be needed
319322// ByteConversion.longToByte(this.recordCount, buf, OFFSET_RECORD_COUNT);
320- return OFFSET_REMAINDER ;
323+ return OFFSET_RECORD_COUNT + LENGTH_RECORD_COUNT ; // 51
321324 }
322325
323326 public void write (final RandomAccessFile raf ) throws IOException {
324327 raf .seek (0 );
325- write (this .buf );
326- raf .write (this .buf );
328+ write (this .headerBuf );
329+ raf .write (this .headerBuf );
327330 this .dirty = false ;
328331 }
329332
@@ -351,4 +354,27 @@ public ReentrantReadWriteLock.WriteLock writeLock() {
351354 writeLock .lock ();
352355 return writeLock ;
353356 }
357+
358+
359+ protected static class AbstractPagedFileHeaderData {
360+ final short version ;
361+ final short headerSize ;
362+ final int pageSize ;
363+ final long totalCount ;
364+ final long firstFreePage ;
365+ final long lastFreePage ;
366+ final byte pageHeaderSize ;
367+ final short maxKeySize ;
368+
369+ private AbstractPagedFileHeaderData (final short version , final short headerSize , final int pageSize , final long totalCount , final long firstFreePage , final long lastFreePage , final byte pageHeaderSize , final short maxKeySize ) {
370+ this .version = version ;
371+ this .headerSize = headerSize ;
372+ this .pageSize = pageSize ;
373+ this .totalCount = totalCount ;
374+ this .firstFreePage = firstFreePage ;
375+ this .lastFreePage = lastFreePage ;
376+ this .pageHeaderSize = pageHeaderSize ;
377+ this .maxKeySize = maxKeySize ;
378+ }
379+ }
354380}
0 commit comments