private void expandIfNecessary ( long dataLength ) throws IOException { long elementLength = Element . HEADER_LENGTH + dataLength ; long remainingBytes = remainingBytes ( ) ; if ( remainingBytes >= elementLength ) return ; // Expand. long previousLength = fileLength ; long newLength ; // Double the length until we can fit the new data. do { remainingBytes += previousLength ; newLength = previousLength << 1 ; previousLength = newLength ; } while ( remainingBytes < elementLength ) ; setLength ( newLength ) ; // Calculate the position of the tail end of the data in the ring buffer long endOfLastElement = wrapPosition ( last . position + Element . HEADER_LENGTH + last . length ) ; long count = 0 ; // If the buffer is split, we need to make it contiguous if ( endOfLastElement <= first . position ) { FileChannel channel = raf . getChannel ( ) ; channel . position ( fileLength ) ; // destination position count = endOfLastElement - headerLength ; if ( channel . transferTo ( headerLength , count , channel ) != count ) { throw new AssertionError ( "Copied insufficient number of bytes!" ) ; } } // Commit the expansion. if ( last . position < first . position ) { long newLastPosition = fileLength + last . position - headerLength ; writeHeader ( newLength , elementCount , first . position , newLastPosition ) ; last = new Element ( newLastPosition , last . length ) ; } else { writeHeader ( newLength , elementCount , first . position , last . position ) ; } fileLength = newLength ; if ( zero ) { ringErase ( headerLength , count ) ; } }
If necessary expands the file to accommodate an additional element of the given length .