/** * Add a Mutation to the commit log. * * @param mutation the Mutation to add to the log */ public ReplayPosition add(Mutation mutation) { assert mutation != null; long size = Mutation.serializer.serializedSize(mutation, MessagingService.current_version); long totalSize = size + ENTRY_OVERHEAD_SIZE; if (totalSize > MAX_MUTATION_SIZE) { throw new IllegalArgumentException( String.format( "Mutation of %s bytes is too large for the maxiumum size of %s", totalSize, MAX_MUTATION_SIZE)); } Allocation alloc = allocator.allocate(mutation, (int) totalSize); ICRC32 checksum = CRC32Factory.instance.create(); final ByteBuffer buffer = alloc.getBuffer(); try (BufferedDataOutputStreamPlus dos = new DataOutputBufferFixed(buffer)) { // checksummed length dos.writeInt((int) size); checksum.update(buffer, buffer.position() - 4, 4); buffer.putInt(checksum.getCrc()); int start = buffer.position(); // checksummed mutation Mutation.serializer.serialize(mutation, dos, MessagingService.current_version); checksum.update(buffer, start, (int) size); buffer.putInt(checksum.getCrc()); } catch (IOException e) { throw new FSWriteError(e, alloc.getSegment().getPath()); } finally { alloc.markWritten(); } executor.finishWriteFor(alloc); return alloc.getReplayPosition(); }