diff --git a/server/src/main/java/org/elasticsearch/index/store/FsDirectoryFactory.java b/server/src/main/java/org/elasticsearch/index/store/FsDirectoryFactory.java index 0561af50cfbd9..3b74a4a49d66d 100644 --- a/server/src/main/java/org/elasticsearch/index/store/FsDirectoryFactory.java +++ b/server/src/main/java/org/elasticsearch/index/store/FsDirectoryFactory.java @@ -163,8 +163,6 @@ public IndexInput openInput(String name, IOContext context) throws IOException { // we need to do these checks on the outer directory since the inner doesn't know about pending deletes ensureOpen(); ensureCanRead(name); - // we switch the context here since mmap checks for the READONCE context by identity - context = context == Store.READONCE_CHECKSUM ? IOContext.READONCE : context; // we only use the mmap to open inputs. Everything else is managed by the NIOFSDirectory otherwise // we might run into trouble with files that are pendingDelete in one directory but still // listed in listAll() from the other. We on the other hand don't want to list files from both dirs @@ -191,7 +189,7 @@ private static String getExtension(String name) { } static boolean useDelegate(String name, IOContext ioContext) { - if (ioContext == Store.READONCE_CHECKSUM) { + if (ioContext.hints().contains(Store.FileFooterOnly.INSTANCE)) { // If we're just reading the footer for the checksum then mmap() isn't really necessary, and it's desperately inefficient // if pre-loading is enabled on this file. return false; diff --git a/server/src/main/java/org/elasticsearch/index/store/Store.java b/server/src/main/java/org/elasticsearch/index/store/Store.java index f7f8d4275156f..27d186137958b 100644 --- a/server/src/main/java/org/elasticsearch/index/store/Store.java +++ b/server/src/main/java/org/elasticsearch/index/store/Store.java @@ -146,19 +146,22 @@ public class Store extends AbstractIndexShardComponent implements Closeable, Ref Property.IndexScope ); + /** + * A {@link org.apache.lucene.store.IOContext.FileOpenHint} that we will only read the Lucene file footer + */ + public enum FileFooterOnly implements IOContext.FileOpenHint { + INSTANCE + } + /** * Specific {@link IOContext} indicating that we will read only the Lucene file footer (containing the file checksum) * See {@link MetadataSnapshot#checksumFromLuceneFile}. */ - public static final IOContext READONCE_CHECKSUM = createReadOnceContext(); - - // while equivalent, these different read once contexts are checked by identity in directory implementations - private static IOContext createReadOnceContext() { - var context = IOContext.READONCE.withHints(DataAccessHint.SEQUENTIAL, ReadOnceHint.INSTANCE); - assert context != IOContext.READONCE; - assert context.equals(IOContext.READONCE); - return context; - } + public static final IOContext READONCE_CHECKSUM = IOContext.READONCE.withHints( + DataAccessHint.SEQUENTIAL, + ReadOnceHint.INSTANCE, + FileFooterOnly.INSTANCE + ); private final AtomicBoolean isClosed = new AtomicBoolean(false); private final StoreDirectory directory; @@ -935,8 +938,6 @@ private static void checksumFromLuceneFile( boolean readFileAsHash, BytesRef writerUuid ) throws IOException { - // We select the read once context carefully here since these constants, while equivalent are - // checked by identity in the different directory implementations. var context = file.startsWith(IndexFileNames.SEGMENTS) ? IOContext.READONCE : READONCE_CHECKSUM; try (IndexInput in = directory.openInput(file, context)) { final long length = in.length(); diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java index d62443e492605..7c229381a5a7c 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java @@ -377,7 +377,7 @@ public IndexInput openInput(final String name, final IOContext context) throws I final BytesRef content = fileInfo.metadata().hash(); return new ByteArrayIndexInput("ByteArrayIndexInput(" + name + ')', content.bytes, content.offset, content.length); } - if (context == Store.READONCE_CHECKSUM) { + if (context.hints().contains(Store.FileFooterOnly.INSTANCE)) { return ChecksumBlobContainerIndexInput.create(fileInfo.physicalName(), fileInfo.length(), fileInfo.checksum(), context); } diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/ChecksumBlobContainerIndexInput.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/ChecksumBlobContainerIndexInput.java index 552c65a6f2550..4636090158988 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/ChecksumBlobContainerIndexInput.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/ChecksumBlobContainerIndexInput.java @@ -115,7 +115,7 @@ private int checksumPositionOrThrow(long pos) { } private static void ensureReadOnceChecksumContext(IOContext context) { - if (context != Store.READONCE_CHECKSUM) { + if (context.hints().contains(Store.FileFooterOnly.INSTANCE) == false) { assert false : "expected READONCE_CHECKSUM but got " + context; throw new IllegalArgumentException("ChecksumBlobContainerIndexInput should only be used with READONCE_CHECKSUM context"); }