Do not use FileChannel.position() in FileChannelJournalSegmentWriter
Description
FileChannelJournalSegmentWriter is using FileChannel methods in sub-optimal way, such as:
// Read more bytes from the segment if necessary.if(memory.remaining()< maxEntrySize){ channel.position(position); memory.clear(); channel.read(memory); channel.position(position); memory.flip();}
and
// Zero entries after the given index.long position = channel.position(); channel.write(zero()); channel.position(position);
FileChannelJournalSegmentWriter is using FileChannel methods in sub-optimal way, such as:
// Read more bytes from the segment if necessary. if (memory.remaining() < maxEntrySize) { channel.position(position); memory.clear(); channel.read(memory); channel.position(position); memory.flip(); }
and
// Zero entries after the given index. long position = channel.position(); channel.write(zero()); channel.position(position);
This incurs syscall overhead and is bad for reasoning as highlighted in CONTROLLER-2094. This manifests as an explicit lseek(SEEK_CUR) at each write, as shown in https://lf-opendaylight.atlassian.net/browse/CONTROLLER-2043#icft=CONTROLLER-2043:
1322466 lseek(109, 0, SEEK_CUR) = 1435610 <0.000009> 1322466 write(109, "\0\1\220\203aE3\367\22\1\200uui\344\254\355\0\5sr\0Corg.opend"..., 102539) = 102539 <0.000033> 1322466 fsync(109)
Reorganize the code to use a field to store the current channel position and use FileChannel.write(ByteBuffer, long) to issue a pwrite(2).
This should eliminate one syscall and reduce locking around FileChannel.positionLock.