private static ReadableLogRecord read ( ByteBuffer viewBuffer , long expectedSequenceNumber , ByteBuffer sourceBuffer ) { ReadableLogRecord logRecord = null ; int absolutePosition = sourceBuffer . position ( ) + viewBuffer . position ( ) ; // Read the record magic number field. final byte [ ] magicNumberBuffer = new byte [ RECORD_MAGIC_NUMBER . length ] ; viewBuffer . get ( magicNumberBuffer ) ; int recordLength = 0 ; if ( Arrays . equals ( magicNumberBuffer , RECORD_MAGIC_NUMBER ) ) { long recordSequenceNumber = viewBuffer . getLong ( ) ; if ( recordSequenceNumber >= expectedSequenceNumber ) { // The record sequence is consistent with the expected sequence number supplied by the // caller. So skip over the actual log record data in this record so that // we can check the tail sequence number. recordLength = viewBuffer . getInt ( ) ; // Preserve the current byte cursor position so that we can reset back to it later. // Move the byte cursor to the first byte after the record data. final int recordDataPosition = viewBuffer . position ( ) ; viewBuffer . position ( recordDataPosition + recordLength ) ; // Read the repeated record sequence number final long tailSequenceNumber = viewBuffer . getLong ( ) ; // Because are are only looking for sequence numbers larger than expected the only assurance that we // have not read garbage following the magic number is that the first and tail sequence numbers are equal. // Note its still possible garbage is in the data but that can't be helped without changing the log format. // It will be discovered later no doubt! if ( tailSequenceNumber == recordSequenceNumber ) { // Return the buffer's pointer to the start of // the record's data prior to creating a new // ReadableLogRecord to return to the caller. viewBuffer . position ( recordDataPosition ) ; logRecord = new ReadableLogRecord ( viewBuffer , absolutePosition , tailSequenceNumber ) ; // Advance the original buffer's position to the end of this record. This ensures that // the next ReadableLogRecord or WritableLogRecord constructed will read or write the // next record in the file. sourceBuffer . position ( absolutePosition + HEADER_SIZE + recordLength ) ; } } } return logRecord ; }
careful with trace in this method as it is called many times from doByteByByteScanning