Skip to content
laforge49 edited this page May 23, 2012 · 15 revisions

A block on disk contains (1) a fixed-length header and (2) a variable-length byte array holding a serialized RootJid object. The header contains one or more of the following:

  1. The length of the variable-length byte array.
  2. A timestamp. And
  3. The checksum of the variable-length byte array.

Implementations of the Block interface model and are used to manage disk blocks. Each implementation handles a different type of header:

  1. LBlock has a 4-byte header which contains only the length of the variable-length byte array.
  2. LTBlock is 12 bytes long and contains both the length and time in milliseconds.
  3. LTA32Block is 20 bytes long and contains the length, time in milliseconds and an Adler32 checksum.

The Block API was designed to support three activities:

  1. Writing a block to disk in one I/O operation.
  2. Reading the block header. And
  3. Reading the variable-length byte array and validating its content.

As a convenience, Blocks also hold a long used as a file position, which is accessed using the getCurrentPosition and setCurrentPosition methods.

##Writing a Block to Disk

block.setRootJid(rootJid);
byte[] bytes = block.serialize();
block.setCurrentPosition(position);
  1. The setRootJid method resets the contents of the Block and saves a reference to a RootJid.
  2. The first time the serialize method is called, the RootJid is serialized, the header is initialized and everything is placed in a byte array--which is then returned, ready to be written to disk. Subsequent calls to serialize simply return the same byte array.
  3. This specifies where the block is to be written.

##Reading a Block Header

int headerLength = block.headerLength();
byte[] headerBytes = new byte[headerLength]
block.setCurrentPosition(position);
...
block.setRootJid(null);
int byteArrayLength = setHeaderBytes(headerBytes);
  1. The headerLength method returns a constant value, though the value varies depending on which implementation of the Block interface is used.
  2. Create the headerBytes into which the header is to be read.
  3. Specify where the block is to be read from.
  4. Read the header.
  5. The setRootJid method is used to rfeset the contents of the block.
  6. The setHeaderBytes method deserializes the header and returns the length of the byte array.

##Reading the Variable-Length Byte Array

byte[] rootJidBytes = new byte[byteArrayLength];
...
boolean valid =  setRootJidBytes(rootJidBytes);
if (!valid) ...
RootJid rootJid = getRootJid(mailbox, parent);
  1. Create the rootJidBytes into which the variable-length byte array is to be read.
  2. Read the variable-length byte array.
  3. The setRootJidBytes saves a reference to rootJidBytes and validates it against the already deserialized header.
  4. Make sure the rootJidBytes are valid.
  5. Create a rootJid from the rootJidBytes.

##JFile Classes Referenced on this Page

Block
LBlock
LTBlock
LTA32Block

Up: Home Next: JFile

Clone this wiki locally