Skip to content

Commit 5f54072

Browse files
authored
Specify a hint that no special IO behavior should be used (#127606)
1 parent c9d0499 commit 5f54072

File tree

5 files changed

+39
-48
lines changed

5 files changed

+39
-48
lines changed

plugins/store-smb/src/main/java/org/elasticsearch/index/store/smb/SmbMmapFsDirectoryFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public final class SmbMmapFsDirectoryFactory extends FsDirectoryFactory {
2525
@Override
2626
protected Directory newFSDirectory(Path location, LockFactory lockFactory, IndexSettings indexSettings) throws IOException {
2727
return new SmbDirectoryWrapper(
28-
setPreload(
28+
setMMapFunctions(
2929
new MMapDirectory(location, lockFactory),
3030
new HashSet<>(indexSettings.getValue(IndexModule.INDEX_STORE_PRE_LOAD_SETTING))
3131
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.index;
11+
12+
import org.apache.lucene.store.IOContext;
13+
14+
/**
15+
* A hint that no special behavior should be set on open files
16+
*/
17+
public enum StandardIOBehaviorHint implements IOContext.FileOpenHint {
18+
INSTANCE
19+
}

server/src/main/java/org/elasticsearch/index/store/FsDirectoryFactory.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
import org.apache.lucene.store.MMapDirectory;
2121
import org.apache.lucene.store.NIOFSDirectory;
2222
import org.apache.lucene.store.NativeFSLockFactory;
23+
import org.apache.lucene.store.ReadAdvice;
2324
import org.apache.lucene.store.SimpleFSLockFactory;
2425
import org.elasticsearch.common.settings.Setting;
2526
import org.elasticsearch.common.settings.Setting.Property;
2627
import org.elasticsearch.core.IOUtils;
2728
import org.elasticsearch.index.IndexModule;
2829
import org.elasticsearch.index.IndexSettings;
30+
import org.elasticsearch.index.StandardIOBehaviorHint;
2931
import org.elasticsearch.index.codec.vectors.es818.DirectIOHint;
3032
import org.elasticsearch.index.shard.ShardPath;
3133
import org.elasticsearch.logging.LogManager;
@@ -36,6 +38,7 @@
3638
import java.nio.file.Files;
3739
import java.nio.file.Path;
3840
import java.util.HashSet;
41+
import java.util.Optional;
3942
import java.util.OptionalLong;
4043
import java.util.Set;
4144
import java.util.function.BiPredicate;
@@ -75,12 +78,12 @@ protected Directory newFSDirectory(Path location, LockFactory lockFactory, Index
7578
// Use Lucene defaults
7679
final FSDirectory primaryDirectory = FSDirectory.open(location, lockFactory);
7780
if (primaryDirectory instanceof MMapDirectory mMapDirectory) {
78-
return new HybridDirectory(lockFactory, setPreload(mMapDirectory, preLoadExtensions));
81+
return new HybridDirectory(lockFactory, setMMapFunctions(mMapDirectory, preLoadExtensions));
7982
} else {
8083
return primaryDirectory;
8184
}
8285
case MMAPFS:
83-
return setPreload(new MMapDirectory(location, lockFactory), preLoadExtensions);
86+
return setMMapFunctions(new MMapDirectory(location, lockFactory), preLoadExtensions);
8487
case SIMPLEFS:
8588
case NIOFS:
8689
return new NIOFSDirectory(location, lockFactory);
@@ -89,10 +92,18 @@ protected Directory newFSDirectory(Path location, LockFactory lockFactory, Index
8992
}
9093
}
9194

95+
private static Optional<ReadAdvice> overrideReadAdvice(String name, IOContext context) {
96+
if (context.hints().contains(StandardIOBehaviorHint.INSTANCE)) {
97+
return Optional.of(ReadAdvice.NORMAL);
98+
}
99+
return Optional.empty();
100+
}
101+
92102
/** Sets the preload, if any, on the given directory based on the extensions. Returns the same directory instance. */
93103
// visibility and extensibility for testing
94-
public MMapDirectory setPreload(MMapDirectory mMapDirectory, Set<String> preLoadExtensions) {
104+
public MMapDirectory setMMapFunctions(MMapDirectory mMapDirectory, Set<String> preLoadExtensions) {
95105
mMapDirectory.setPreload(getPreloadFunc(preLoadExtensions));
106+
mMapDirectory.setReadAdviceOverride(FsDirectoryFactory::overrideReadAdvice);
96107
return mMapDirectory;
97108
}
98109

server/src/test/java/org/elasticsearch/index/store/FsDirectoryFactoryTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static class PreLoadExposingFsDirectoryFactory extends FsDirectoryFactory {
8888
final Map<MMapDirectory, BiPredicate<String, IOContext>> preLoadFuncMap = new HashMap<>();
8989

9090
@Override
91-
public MMapDirectory setPreload(MMapDirectory mMapDirectory, Set<String> preLoadExtensions) {
91+
public MMapDirectory setMMapFunctions(MMapDirectory mMapDirectory, Set<String> preLoadExtensions) {
9292
var preLoadFunc = FsDirectoryFactory.getPreloadFunc(preLoadExtensions);
9393
mMapDirectory.setPreload(preLoadFunc);
9494
preLoadFuncMap.put(mMapDirectory, preLoadFunc);

x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/CachedBlobContainerIndexInput.java

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@
99

1010
import org.apache.logging.log4j.LogManager;
1111
import org.apache.logging.log4j.Logger;
12-
import org.apache.lucene.store.FlushInfo;
1312
import org.apache.lucene.store.IOContext;
14-
import org.apache.lucene.store.MergeInfo;
15-
import org.apache.lucene.store.ReadAdvice;
1613
import org.elasticsearch.blobcache.BlobCacheUtils;
1714
import org.elasticsearch.blobcache.common.ByteRange;
15+
import org.elasticsearch.index.StandardIOBehaviorHint;
1816
import org.elasticsearch.index.snapshots.blobstore.BlobStoreIndexShardSnapshot.FileInfo;
1917
import org.elasticsearch.xpack.searchablesnapshots.cache.common.CacheFile;
2018
import org.elasticsearch.xpack.searchablesnapshots.store.IndexInputStats;
@@ -23,8 +21,6 @@
2321
import java.io.IOException;
2422
import java.io.InputStream;
2523
import java.nio.ByteBuffer;
26-
import java.util.Optional;
27-
import java.util.Set;
2824
import java.util.concurrent.atomic.AtomicLong;
2925
import java.util.function.Predicate;
3026
import java.util.function.Supplier;
@@ -40,42 +36,7 @@ public class CachedBlobContainerIndexInput extends MetadataCachingIndexInput {
4036
* a complete part of the {@link #fileInfo} at once in the cache and should not be
4137
* used for anything else than what the {@link #prefetchPart(int, Supplier)} method does.
4238
*/
43-
public static final IOContext CACHE_WARMING_CONTEXT = new IOContext() {
44-
@Override
45-
public Context context() {
46-
return Context.DEFAULT;
47-
}
48-
49-
@Override
50-
public MergeInfo mergeInfo() {
51-
return null;
52-
}
53-
54-
@Override
55-
public FlushInfo flushInfo() {
56-
return null;
57-
}
58-
59-
@Override
60-
public Set<FileOpenHint> hints() {
61-
return Set.of();
62-
}
63-
64-
@Override
65-
public IOContext withHints(FileOpenHint... hints) {
66-
return this;
67-
}
68-
69-
@Override
70-
public Optional<ReadAdvice> readAdvice() {
71-
return Optional.of(ReadAdvice.NORMAL);
72-
}
73-
74-
@Override
75-
public IOContext withReadAdvice(ReadAdvice advice) {
76-
return this;
77-
}
78-
};
39+
public static final IOContext CACHE_WARMING_CONTEXT = IOContext.DEFAULT.withHints(StandardIOBehaviorHint.INSTANCE);
7940

8041
private static final Logger logger = LogManager.getLogger(CachedBlobContainerIndexInput.class);
8142

@@ -141,7 +102,7 @@ private CachedBlobContainerIndexInput(
141102

142103
@Override
143104
protected void readWithoutBlobCache(ByteBuffer b) throws Exception {
144-
ensureContext(ctx -> ctx != CACHE_WARMING_CONTEXT);
105+
ensureContext(ctx -> ctx.hints().contains(StandardIOBehaviorHint.INSTANCE) == false);
145106
final long position = getAbsolutePosition();
146107
final int length = b.remaining();
147108

@@ -178,7 +139,7 @@ public long getPersistentCacheInitialLength() throws Exception {
178139
* or {@code -1} if the prewarming was cancelled
179140
*/
180141
public long prefetchPart(final int part, Supplier<Boolean> isCancelled) throws IOException {
181-
ensureContext(ctx -> ctx == CACHE_WARMING_CONTEXT);
142+
ensureContext(ctx -> ctx.hints().contains(StandardIOBehaviorHint.INSTANCE));
182143
if (part >= fileInfo.numberOfParts()) {
183144
throw new IllegalArgumentException("Unexpected part number [" + part + "]");
184145
}

0 commit comments

Comments
 (0)