dataFile.incrementLength(writeRecord.location.getSize());
writes.offer(writeRecord);
}
Location perform(RandomAccessFile file, ReplicationTarget replicator, boolean checksum) throws IOException {
DataByteArrayOutputStream buffer = new DataByteArrayOutputStream(size);
boolean forceToDisk = false;
WriteCommand latest = null;
// Write an empty batch control record.
buffer.reset();
buffer.writeInt(BATCH_CONTROL_RECORD_SIZE);
buffer.writeByte(Location.BATCH_CONTROL_RECORD_TYPE);
buffer.writeInt(0);
buffer.write(BATCH_CONTROL_RECORD_MAGIC);
buffer.writeLong(0);
WriteCommand control = writes.peek();
Iterator<WriteCommand> commands = writes.iterator();
// Skip the control write:
commands.next();
// Process others:
while (commands.hasNext()) {
WriteCommand current = commands.next();
forceToDisk |= current.sync;
buffer.writeInt(current.location.getSize());
buffer.writeByte(current.location.getType());
buffer.write(current.data.getData(), current.data.getOffset(), current.data.getLength());
latest = current;
}
// Now we can fill in the batch control record properly.
Buffer sequence = buffer.toBuffer();
buffer.reset();
buffer.skip(Journal.HEADER_SIZE);
buffer.writeInt(sequence.getLength() - Journal.HEADER_SIZE - Journal.BATCH_SIZE);
buffer.skip(Journal.BATCH_CONTROL_RECORD_MAGIC.length);
if (checksum) {
Checksum adler32 = new Adler32();
adler32.update(sequence.getData(), sequence.getOffset() + Journal.BATCH_CONTROL_RECORD_SIZE, sequence.getLength() - Journal.BATCH_CONTROL_RECORD_SIZE);
buffer.writeLong(adler32.getValue());
}
// Now do the 1 big write.
file.seek(offset);
file.write(sequence.getData(), sequence.getOffset(), sequence.getLength());