class LockedReadFileInput extends SimpleFileInput {
    /** Segment for read. */
    private final long segmentId;

    /** Holder of actual information of latest manipulation on WAL segments. */
    private final SegmentAware segmentAware;

    /** Factory of file I/O for segment. */
    private final SegmentIoFactory fileIOFactory;

    /** Last read was from archive or not. */
    private boolean isLastReadFromArchive;

    /**
     * @param buf Buffer for reading blocks of data into.
     * @param initFileIo Initial File I/O for reading.
     * @param segmentAware Holder of actual information of latest manipulation on WAL segments.
     * @param segmentIOFactory Factory of file I/O for segment.
     * @throws IOException if initFileIo would be fail during reading.
     */
    LockedReadFileInput(
        ByteBufferExpander buf,
        SegmentIO initFileIo,
        SegmentAware segmentAware,
        SegmentIoFactory segmentIOFactory
    ) throws IOException {
        super(initFileIo, buf);
        this.segmentAware = segmentAware;
        this.fileIOFactory = segmentIOFactory;
        this.segmentId = initFileIo.getSegmentId();
        isLastReadFromArchive = segmentAware.lastArchivedAbsoluteIndex() >= initFileIo.getSegmentId();
    }

    /** {@inheritDoc} */
    @Override public void ensure(int requested) throws IOException {<FILL_FUNCTION_BODY>}

    /**
     * Refresh current file io.
     *
     * @throws IOException if old fileIO is fail during reading or new file is fail during creation.
     */
    private void refreshIO() throws IOException {
        FileIO io = fileIOFactory.build(segmentId);

        io.position(io().position());

        io().close();

        this.io = io;
    }

    /**
     * Resolving fileIo for segment.
     */
    interface SegmentIoFactory {
        /**
         * @param segmentId Segment for IO action.
         * @return {@link FileIO}.
         * @throws IOException if creation would be fail.
         */
        FileIO build(long segmentId) throws IOException;
    }
}

        int available = buffer().remaining();

        if (available >= requested)
            return;

        // Segment deletion protection.
        if (!segmentAware.reserve(segmentId))
            throw new FileNotFoundException("Segment does not exist: " + segmentId);

        try {
            // Protection against transferring a segment to the archive by #archiver.
            boolean readArchive = !segmentAware.lock(segmentId);
            try {
                if (readArchive && !isLastReadFromArchive) {
                    isLastReadFromArchive = true;

                    refreshIO();
                }

                super.ensure(requested);
            }
            finally {
                if (!readArchive)
                    segmentAware.unlock(segmentId);
            }
        }
        finally {
            segmentAware.release(segmentId);
        }
    
<methods>public void <init>(org.apache.ignite.internal.processors.cache.persistence.file.FileIO, org.apache.ignite.internal.processors.cache.persistence.wal.ByteBufferExpander) throws java.io.IOException,public java.nio.ByteBuffer buffer() ,public void ensure(int) throws java.io.IOException,public org.apache.ignite.internal.processors.cache.persistence.file.FileIO io() ,public long position() ,public boolean readBoolean() throws java.io.IOException,public byte readByte() throws java.io.IOException,public char readChar() throws java.io.IOException,public double readDouble() throws java.io.IOException,public float readFloat() throws java.io.IOException,public void readFully(byte[]) throws java.io.IOException,public void readFully(byte[], int, int) throws java.io.IOException,public int readInt() throws java.io.IOException,public java.lang.String readLine() throws java.io.IOException,public long readLong() throws java.io.IOException,public short readShort() throws java.io.IOException,public java.lang.String readUTF() throws java.io.IOException,public int readUnsignedByte() throws java.io.IOException,public int readUnsignedShort() throws java.io.IOException,public void seek(long) throws java.io.IOException,public int skipBytes(int) throws java.io.IOException,public org.apache.ignite.internal.processors.cache.persistence.wal.io.FileInput.Crc32CheckingFileInput startRead(boolean) <variables>private java.nio.ByteBuffer buf,private org.apache.ignite.internal.processors.cache.persistence.wal.ByteBufferExpander expBuf,protected org.apache.ignite.internal.processors.cache.persistence.file.FileIO io,private long pos