|
20 | 20 | import org.apache.lucene.store.MMapDirectory; |
21 | 21 | import org.apache.lucene.store.NIOFSDirectory; |
22 | 22 | import org.apache.lucene.store.NativeFSLockFactory; |
| 23 | +import org.apache.lucene.store.ReadAdvice; |
23 | 24 | import org.apache.lucene.store.SimpleFSLockFactory; |
24 | 25 | import org.elasticsearch.common.settings.Setting; |
25 | 26 | import org.elasticsearch.common.settings.Setting.Property; |
| 27 | +import org.elasticsearch.common.util.FeatureFlag; |
26 | 28 | import org.elasticsearch.core.IOUtils; |
27 | 29 | import org.elasticsearch.index.IndexModule; |
28 | 30 | import org.elasticsearch.index.IndexSettings; |
|
43 | 45 | public class FsDirectoryFactory implements IndexStorePlugin.DirectoryFactory { |
44 | 46 |
|
45 | 47 | private static final Logger Log = LogManager.getLogger(FsDirectoryFactory.class); |
| 48 | + private static final FeatureFlag MADV_RANDOM_FEATURE_FLAG = new FeatureFlag("madv_random"); |
46 | 49 |
|
47 | 50 | public static final Setting<LockFactory> INDEX_LOCK_FACTOR_SETTING = new Setting<>("index.store.fs.fs_lock", "native", (s) -> { |
48 | 51 | return switch (s) { |
@@ -75,12 +78,20 @@ protected Directory newFSDirectory(Path location, LockFactory lockFactory, Index |
75 | 78 | // Use Lucene defaults |
76 | 79 | final FSDirectory primaryDirectory = FSDirectory.open(location, lockFactory); |
77 | 80 | if (primaryDirectory instanceof MMapDirectory mMapDirectory) { |
78 | | - return new HybridDirectory(lockFactory, setPreload(mMapDirectory, preLoadExtensions)); |
| 81 | + Directory dir = new HybridDirectory(lockFactory, setPreload(mMapDirectory, preLoadExtensions)); |
| 82 | + if (MADV_RANDOM_FEATURE_FLAG.isEnabled() == false) { |
| 83 | + dir = disableRandomAdvice(dir); |
| 84 | + } |
| 85 | + return dir; |
79 | 86 | } else { |
80 | 87 | return primaryDirectory; |
81 | 88 | } |
82 | 89 | case MMAPFS: |
83 | | - return setPreload(new MMapDirectory(location, lockFactory), preLoadExtensions); |
| 90 | + Directory dir = setPreload(new MMapDirectory(location, lockFactory), preLoadExtensions); |
| 91 | + if (MADV_RANDOM_FEATURE_FLAG.isEnabled() == false) { |
| 92 | + dir = disableRandomAdvice(dir); |
| 93 | + } |
| 94 | + return dir; |
84 | 95 | case SIMPLEFS: |
85 | 96 | case NIOFS: |
86 | 97 | return new NIOFSDirectory(location, lockFactory); |
@@ -108,6 +119,23 @@ static BiPredicate<String, IOContext> getPreloadFunc(Set<String> preLoadExtensio |
108 | 119 | return MMapDirectory.NO_FILES; |
109 | 120 | } |
110 | 121 |
|
| 122 | + /** |
| 123 | + * Return a {@link FilterDirectory} around the provided {@link Directory} that forcefully disables {@link IOContext#readAdvice random |
| 124 | + * access}. |
| 125 | + */ |
| 126 | + static Directory disableRandomAdvice(Directory dir) { |
| 127 | + return new FilterDirectory(dir) { |
| 128 | + @Override |
| 129 | + public IndexInput openInput(String name, IOContext context) throws IOException { |
| 130 | + if (context.readAdvice() == ReadAdvice.RANDOM) { |
| 131 | + context = context.withReadAdvice(ReadAdvice.NORMAL); |
| 132 | + } |
| 133 | + assert context.readAdvice() != ReadAdvice.RANDOM; |
| 134 | + return super.openInput(name, context); |
| 135 | + } |
| 136 | + }; |
| 137 | + } |
| 138 | + |
111 | 139 | /** |
112 | 140 | * Returns true iff the directory is a hybrid fs directory |
113 | 141 | */ |
|
0 commit comments