|
19 | 19 | import org.apache.lucene.store.MMapDirectory; |
20 | 20 | import org.apache.lucene.store.NIOFSDirectory; |
21 | 21 | import org.apache.lucene.store.NativeFSLockFactory; |
| 22 | +import org.apache.lucene.store.ReadAdvice; |
22 | 23 | import org.apache.lucene.store.SimpleFSLockFactory; |
23 | 24 | import org.elasticsearch.common.settings.Setting; |
24 | 25 | import org.elasticsearch.common.settings.Setting.Property; |
| 26 | +import org.elasticsearch.common.util.FeatureFlag; |
25 | 27 | import org.elasticsearch.core.IOUtils; |
26 | 28 | import org.elasticsearch.index.IndexModule; |
27 | 29 | import org.elasticsearch.index.IndexSettings; |
|
37 | 39 |
|
38 | 40 | public class FsDirectoryFactory implements IndexStorePlugin.DirectoryFactory { |
39 | 41 |
|
| 42 | + private static final FeatureFlag MADV_RANDOM_FEATURE_FLAG = new FeatureFlag("madv_random"); |
| 43 | + |
40 | 44 | public static final Setting<LockFactory> INDEX_LOCK_FACTOR_SETTING = new Setting<>("index.store.fs.fs_lock", "native", (s) -> { |
41 | 45 | return switch (s) { |
42 | 46 | case "native" -> NativeFSLockFactory.INSTANCE; |
@@ -68,12 +72,20 @@ protected Directory newFSDirectory(Path location, LockFactory lockFactory, Index |
68 | 72 | // Use Lucene defaults |
69 | 73 | final FSDirectory primaryDirectory = FSDirectory.open(location, lockFactory); |
70 | 74 | if (primaryDirectory instanceof MMapDirectory mMapDirectory) { |
71 | | - return new HybridDirectory(lockFactory, setPreload(mMapDirectory, preLoadExtensions)); |
| 75 | + Directory dir = new HybridDirectory(lockFactory, setPreload(mMapDirectory, preLoadExtensions)); |
| 76 | + if (MADV_RANDOM_FEATURE_FLAG.isEnabled() == false) { |
| 77 | + dir = disableRandomAdvice(dir); |
| 78 | + } |
| 79 | + return dir; |
72 | 80 | } else { |
73 | 81 | return primaryDirectory; |
74 | 82 | } |
75 | 83 | case MMAPFS: |
76 | | - return setPreload(new MMapDirectory(location, lockFactory), preLoadExtensions); |
| 84 | + Directory dir = setPreload(new MMapDirectory(location, lockFactory), preLoadExtensions); |
| 85 | + if (MADV_RANDOM_FEATURE_FLAG.isEnabled() == false) { |
| 86 | + dir = disableRandomAdvice(dir); |
| 87 | + } |
| 88 | + return dir; |
77 | 89 | case SIMPLEFS: |
78 | 90 | case NIOFS: |
79 | 91 | return new NIOFSDirectory(location, lockFactory); |
@@ -101,6 +113,23 @@ static BiPredicate<String, IOContext> getPreloadFunc(Set<String> preLoadExtensio |
101 | 113 | return MMapDirectory.NO_FILES; |
102 | 114 | } |
103 | 115 |
|
| 116 | + /** |
| 117 | + * Return a {@link FilterDirectory} around the provided {@link Directory} that forcefully disables {@link IOContext#readAdvice random |
| 118 | + * access}. |
| 119 | + */ |
| 120 | + static Directory disableRandomAdvice(Directory dir) { |
| 121 | + return new FilterDirectory(dir) { |
| 122 | + @Override |
| 123 | + public IndexInput openInput(String name, IOContext context) throws IOException { |
| 124 | + if (context.readAdvice() == ReadAdvice.RANDOM) { |
| 125 | + context = context.withReadAdvice(ReadAdvice.NORMAL); |
| 126 | + } |
| 127 | + assert context.readAdvice() != ReadAdvice.RANDOM; |
| 128 | + return super.openInput(name, context); |
| 129 | + } |
| 130 | + }; |
| 131 | + } |
| 132 | + |
104 | 133 | /** |
105 | 134 | * Returns true iff the directory is a hybrid fs directory |
106 | 135 | */ |
|
0 commit comments