Use ReadAdvice.RANDOM by default. (#13244)

This switches the default `ReadAdvice` from `NORMAL` to `RANDOM`, which is a better fit for the kind of access pattern that Lucene has. This is expected to reduce page cache trashing and contention on the page table.

`NORMAL` is still available, but never used by any of the file formats.
This commit is contained in:
Adrien Grand 2024-04-04 16:45:41 +02:00 committed by GitHub
parent 54a2e11434
commit a2676b1b26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 16 additions and 12 deletions

View File

@ -157,7 +157,14 @@ Bug Fixes
* GITHUB#12878: Fix the declared Exceptions of Expression#evaluate() to match those * GITHUB#12878: Fix the declared Exceptions of Expression#evaluate() to match those
of DoubleValues#doubleValue(). (Uwe Schindler) of DoubleValues#doubleValue(). (Uwe Schindler)
Changes in Runtime Behavior
---------------------
* GITHUB#13244: IOContext now uses ReadAdvice#RANDOM by default for read
operations. An implication is that `MMapDirectory` will use POSIX_MADV_RANDOM
on POSIX systems. (Adrien Grand)
Changes in Backwards Compatibility Policy Changes in Backwards Compatibility Policy
----------------------------------------- -----------------------------------------

View File

@ -49,7 +49,7 @@ public record IOContext(
* A default context for normal reads/writes. Use {@link #withReadAdvice(ReadAdvice)} to specify * A default context for normal reads/writes. Use {@link #withReadAdvice(ReadAdvice)} to specify
* another {@link ReadAdvice}. * another {@link ReadAdvice}.
*/ */
public static final IOContext DEFAULT = new IOContext(ReadAdvice.NORMAL); public static final IOContext DEFAULT = new IOContext(ReadAdvice.RANDOM);
/** A default context for reads with {@link ReadAdvice#SEQUENTIAL}. */ /** A default context for reads with {@link ReadAdvice#SEQUENTIAL}. */
public static final IOContext READONCE = new IOContext(ReadAdvice.SEQUENTIAL); public static final IOContext READONCE = new IOContext(ReadAdvice.SEQUENTIAL);
@ -67,13 +67,10 @@ public record IOContext(
case FLUSH -> Objects.requireNonNull( case FLUSH -> Objects.requireNonNull(
flushInfo, "flushInfo must not be null if context is FLUSH"); flushInfo, "flushInfo must not be null if context is FLUSH");
} }
if (context == Context.MERGE && readAdvice != ReadAdvice.SEQUENTIAL) { if ((context == Context.FLUSH || context == Context.MERGE)
&& readAdvice != ReadAdvice.SEQUENTIAL) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The MERGE context must use the SEQUENTIAL read access advice"); "The FLUSH and MERGE contexts must use the SEQUENTIAL read access advice");
}
if (context == Context.FLUSH && readAdvice != ReadAdvice.NORMAL) {
throw new IllegalArgumentException(
"The FLUSH context must use the NORMAL read access advice");
} }
} }
@ -84,7 +81,7 @@ public record IOContext(
/** Creates an {@link IOContext} for flushing. */ /** Creates an {@link IOContext} for flushing. */
public IOContext(FlushInfo flushInfo) { public IOContext(FlushInfo flushInfo) {
this(Context.FLUSH, null, flushInfo, ReadAdvice.NORMAL); this(Context.FLUSH, null, flushInfo, ReadAdvice.SEQUENTIAL);
} }
/** Creates an {@link IOContext} for merging. */ /** Creates an {@link IOContext} for merging. */

View File

@ -98,8 +98,8 @@ public class TestMMapDirectory extends BaseDirectoryTestCase {
MMapDirectory.supportsMadvise()); MMapDirectory.supportsMadvise());
} }
// Opens the input with IOContext.RANDOM to ensure basic code path coverage for POSIX_MADV_RANDOM. // Opens the input with ReadAdvice.NORMAL to ensure basic code path coverage.
public void testWithRandom() throws Exception { public void testWithNormal() throws Exception {
final int size = 8 * 1024; final int size = 8 * 1024;
byte[] bytes = new byte[size]; byte[] bytes = new byte[size];
random().nextBytes(bytes); random().nextBytes(bytes);
@ -110,7 +110,7 @@ public class TestMMapDirectory extends BaseDirectoryTestCase {
} }
try (final IndexInput in = try (final IndexInput in =
dir.openInput("test", IOContext.DEFAULT.withReadAdvice(ReadAdvice.RANDOM))) { dir.openInput("test", IOContext.DEFAULT.withReadAdvice(ReadAdvice.NORMAL))) {
final byte[] readBytes = new byte[size]; final byte[] readBytes = new byte[size];
in.readBytes(readBytes, 0, readBytes.length); in.readBytes(readBytes, 0, readBytes.length);
assertArrayEquals(bytes, readBytes); assertArrayEquals(bytes, readBytes);