NioJournalFileRecord implements NioJournalConstants { public static FindResult findNextRecord(UUID delimiter, ByteBuffer source) { final byte hook = RECORD_DELIMITER_PREFIX[0]; if (source.hasRemaining()) { do { if (source.get() == hook) { int originalSourcePosition = source.position(); source.position(originalSourcePosition - 1); final int recordLength = readRecordHeader(source, delimiter); final ReadStatus readStatus = ReadStatus.decode(recordLength); switch (readStatus) { case ReadOk: final int crc32 = extractCrc32FromRecord(source); final int position = source.position(); final FindResult findResult = new FindResult(readStatus, new NioJournalFileRecord(delimiter, (ByteBuffer) source.duplicate().limit(position + recordLength), crc32)); source.position(position + recordLength + RECORD_TRAILER_SIZE); return findResult; case FoundPartialRecord: return new FindResult(readStatus, null); case FoundHeaderWithDifferentDelimiter: if (trace) { log.trace("Quickly iterating other log entry."); } break; default: source.position(Math.max(source.position(), originalSourcePosition)); } } } while (source.hasRemaining()); } return new FindResult(ReadStatus.NoHeaderInBuffer, null); } NioJournalFileRecord(UUID delimiter);   NioJournalFileRecord(UUID delimiter, ByteBuffer payload, int payloadCrc32); static String bufferToString(ByteBuffer buffer); static FindResult findNextRecord(UUID delimiter, ByteBuffer source); static NioJournalFileRecord readRecord(UUID delimiter, ByteBuffer source); static Iterable<NioJournalFileRecord> readRecords(UUID delimiter, FileChannel channel, boolean includeInvalid); static int calculateRequiredBytes(Collection<NioJournalFileRecord> records); static void disposeAll(Collection<NioJournalFileRecord> records); void dispose(); ByteBuffer createEmptyPayload(int payloadSize); void writeRecord(UUID targetDelimiter, ByteBuffer target); int getRecordSize(); ByteBuffer getPayload(); UUID getDelimiter(); boolean isValid(); @Override String toString(); static final int RECORD_LENGTH_OFFSET; static final int RECORD_CRC32_OFFSET; static final int RECORD_HEADER_SIZE; static final int RECORD_TRAILER_SIZE; static final int REVERSE_RECORD_CRC32_OFFSET; }
@Test public void testFindsForwardLookingPartialRecords() throws Exception { final byte[] chunk = new byte[8 * 1024]; final byte[] recordBytes = recordToBytes(); final ByteBuffer byteBuffer = wrap(chunk); for (int i = (chunk.length - recordBytes.length) + 1; i < chunk.length; i++) { createNoise(chunk); arraycopy(recordBytes, 0, chunk, i, chunk.length - i); byteBuffer.clear(); NioJournalFileRecord.FindResult result = findNextRecord(expectedDelimiter, byteBuffer); assertEquals(FoundPartialRecord, result.getStatus()); assertEquals("didn't find correct partial record position.", i, byteBuffer.position()); } }