Repository: apache/kafka
File: storage/src/main/java/org/apache/kafka/storage/internals/log/AbstractIndex.java (Java)

Code before:
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * The abstract index class which holds entry format agnostic methods.
 */
public abstract class AbstractIndex implements Closeable {

    private enum SearchResultType {
        LARGEST_LOWER_BOUND, SMALLEST_UPPER_BOUND
    }

    private static final Logger log = LoggerFactory.getLogger(AbstractIndex.class);

    // Serializes all index operations that mutate internal state.
    // Clients only read committed data and are not affected by concurrent appends/truncates.
    // In the rare case, when the data is truncated, the follower could read inconsistent data.
    // The follower has the logic to ignore the inconsistent data through crc and leader epoch.
    private final ReentrantLock lock = new ReentrantLock();
    // Allows concurrent read operations while ensuring exclusive access if the underlying mmap is changed
    private final ReentrantReadWriteLock remapLock = new ReentrantReadWriteLock();

    private final long baseOffset;
    private final int maxIndexSize;
    private final boolean writable;

    private volatile File file;

    // Length of the index file
    private volatile long length;

    private volatile MappedByteBuffer mmap;

    /**
     * The maximum number of entries this index can hold
     */
    private volatile int maxEntries;
    /** The number of entries in this index */
    private volatile int entries;


    /**
     * @param file The index file

Review comment (performance):
Actually, I meant to only replace the first item, not the whole thing. Could we use the following?

```
    // Serializes all index operations that mutate internal state.
    // Readers do not need to acquire this lock because:
    //  1) MappedByteBuffer provides direct access to the OS-level buffer cache,
    //     which allows concurrent reads in practice.
    //  2) Clients only read committed data and are not affected by concurrent appends/truncates.
    //     In the rare case when the data is truncated, the follower could read inconsistent data.
    //     The follower has the logic to ignore the inconsistent data through crc and leader epoch.
    //  3) Read and remap operations are coordinated via remapLock to ensure visibility of the
           underlying mmap.
```

Code after:
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * The abstract index class which holds entry format agnostic methods.
 */
public abstract class AbstractIndex implements Closeable {

    private enum SearchResultType {
        LARGEST_LOWER_BOUND, SMALLEST_UPPER_BOUND
    }

    private static final Logger log = LoggerFactory.getLogger(AbstractIndex.class);

    // Serializes all index operations that mutate internal state.
    // Readers do not need to acquire this lock because:
    //  1) MappedByteBuffer provides direct access to the OS-level buffer cache,
    //     which allows concurrent reads in practice.
    //  2) Clients only read committed data and are not affected by concurrent appends/truncates.
    //     In the rare case when the data is truncated, the follower could read inconsistent data.
    //     The follower has the logic to ignore the inconsistent data through crc and leader epoch.
    //  3) Read and remap operations are coordinated via remapLock to ensure visibility of the
    //     underlying mmap.
    private final ReentrantLock lock = new ReentrantLock();
    // Allows concurrent read operations while ensuring exclusive access if the underlying mmap is changed
    private final ReentrantReadWriteLock remapLock = new ReentrantReadWriteLock();

    private final long baseOffset;
    private final int maxIndexSize;
    private final boolean writable;

    private volatile File file;

    // Length of the index file
    private volatile long length;

    private volatile MappedByteBuffer mmap;

    /**
     * The maximum number of entries this index can hold
     */
    private volatile int maxEntries;
    /** The number of entries in this index */