2121
2222import org .apache .lucene .search .similarities .BM25Similarity ;
2323import org .apache .lucene .search .similarities .Similarity ;
24+ import org .apache .lucene .store .MMapDirectory ;
25+ import org .apache .lucene .util .Constants ;
2426import org .apache .lucene .util .SetOnce ;
2527import org .elasticsearch .Version ;
2628import org .elasticsearch .client .Client ;
27- import org .elasticsearch .common .Strings ;
2829import org .elasticsearch .common .TriFunction ;
2930import org .elasticsearch .common .io .stream .NamedWriteableRegistry ;
3031import org .elasticsearch .common .settings .Setting ;
5960import java .util .HashMap ;
6061import java .util .HashSet ;
6162import java .util .List ;
62- import java .util .Locale ;
6363import java .util .Map ;
6464import java .util .Objects ;
6565import java .util .Set ;
8484 */
8585public final class IndexModule {
8686
87+ public static final Setting <Boolean > NODE_STORE_ALLOW_MMAPFS = Setting .boolSetting ("node.store.allow_mmapfs" , true , Property .NodeScope );
88+
8789 public static final Setting <String > INDEX_STORE_TYPE_SETTING =
88- new Setting <>("index.store.type" , "" , Function .identity (), Property .IndexScope , Property .NodeScope );
90+ new Setting <>("index.store.type" , "" , Function .identity (), Property .IndexScope , Property .NodeScope );
8991
9092 /** On which extensions to load data into the file-system cache upon opening of files.
9193 * This only works with the mmap directory, and even in that case is still
@@ -289,7 +291,7 @@ IndexEventListener freeze() { // pkg private for testing
289291 }
290292 }
291293
292- private static boolean isBuiltinType (String storeType ) {
294+ public static boolean isBuiltinType (String storeType ) {
293295 for (Type type : Type .values ()) {
294296 if (type .match (storeType )) {
295297 return true ;
@@ -298,21 +300,48 @@ private static boolean isBuiltinType(String storeType) {
298300 return false ;
299301 }
300302
303+
301304 public enum Type {
302- NIOFS ,
303- MMAPFS ,
304- SIMPLEFS ,
305- FS ;
305+ NIOFS ("niofs" ),
306+ MMAPFS ("mmapfs" ),
307+ SIMPLEFS ("simplefs" ),
308+ FS ("fs" );
309+
310+ private final String settingsKey ;
311+
312+ Type (final String settingsKey ) {
313+ this .settingsKey = settingsKey ;
314+ }
315+
316+ private static final Map <String , Type > TYPES ;
317+
318+ static {
319+ final Map <String , Type > types = new HashMap <>(4 );
320+ for (final Type type : values ()) {
321+ types .put (type .settingsKey , type );
322+ }
323+ TYPES = Collections .unmodifiableMap (types );
324+ }
306325
307326 public String getSettingsKey () {
308- return this .name ().toLowerCase (Locale .ROOT );
327+ return this .settingsKey ;
328+ }
329+
330+ public static Type fromSettingsKey (final String key ) {
331+ final Type type = TYPES .get (key );
332+ if (type == null ) {
333+ throw new IllegalArgumentException ("no matching type for [" + key + "]" );
334+ }
335+ return type ;
309336 }
337+
310338 /**
311339 * Returns true iff this settings matches the type.
312340 */
313341 public boolean match (String setting ) {
314342 return getSettingsKey ().equals (setting );
315343 }
344+
316345 }
317346
318347 /**
@@ -325,6 +354,16 @@ public interface IndexSearcherWrapperFactory {
325354 IndexSearcherWrapper newWrapper (IndexService indexService );
326355 }
327356
357+ public static Type defaultStoreType (final boolean allowMmapfs ) {
358+ if (allowMmapfs && Constants .JRE_IS_64BIT && MMapDirectory .UNMAP_SUPPORTED ) {
359+ return Type .MMAPFS ;
360+ } else if (Constants .WINDOWS ) {
361+ return Type .SIMPLEFS ;
362+ } else {
363+ return Type .NIOFS ;
364+ }
365+ }
366+
328367 public IndexService newIndexService (
329368 NodeEnvironment environment ,
330369 NamedXContentRegistry xContentRegistry ,
@@ -343,20 +382,7 @@ public IndexService newIndexService(
343382 IndexSearcherWrapperFactory searcherWrapperFactory = indexSearcherWrapper .get () == null
344383 ? (shard ) -> null : indexSearcherWrapper .get ();
345384 eventListener .beforeIndexCreated (indexSettings .getIndex (), indexSettings .getSettings ());
346- final String storeType = indexSettings .getValue (INDEX_STORE_TYPE_SETTING );
347- final IndexStore store ;
348- if (Strings .isEmpty (storeType ) || isBuiltinType (storeType )) {
349- store = new IndexStore (indexSettings );
350- } else {
351- Function <IndexSettings , IndexStore > factory = indexStoreFactories .get (storeType );
352- if (factory == null ) {
353- throw new IllegalArgumentException ("Unknown store type [" + storeType + "]" );
354- }
355- store = factory .apply (indexSettings );
356- if (store == null ) {
357- throw new IllegalStateException ("store must not be null" );
358- }
359- }
385+ final IndexStore store = getIndexStore (indexSettings , indexStoreFactories );
360386 final QueryCache queryCache ;
361387 if (indexSettings .getValue (INDEX_QUERY_CACHE_ENABLED_SETTING )) {
362388 BiFunction <IndexSettings , IndicesQueryCache , QueryCache > queryCacheProvider = forceQueryCacheProvider .get ();
@@ -375,6 +401,39 @@ public IndexService newIndexService(
375401 indicesFieldDataCache , searchOperationListeners , indexOperationListeners , namedWriteableRegistry );
376402 }
377403
404+ private static IndexStore getIndexStore (
405+ final IndexSettings indexSettings , final Map <String , Function <IndexSettings , IndexStore >> indexStoreFactories ) {
406+ final String storeType = indexSettings .getValue (INDEX_STORE_TYPE_SETTING );
407+ final Type type ;
408+ final Boolean allowMmapfs = NODE_STORE_ALLOW_MMAPFS .get (indexSettings .getNodeSettings ());
409+ if (storeType .isEmpty () || Type .FS .getSettingsKey ().equals (storeType )) {
410+ type = defaultStoreType (allowMmapfs );
411+ } else {
412+ if (isBuiltinType (storeType )) {
413+ type = Type .fromSettingsKey (storeType );
414+ } else {
415+ type = null ;
416+ }
417+ }
418+ if (type != null && type == Type .MMAPFS && allowMmapfs == false ) {
419+ throw new IllegalArgumentException ("store type [mmapfs] is not allowed" );
420+ }
421+ final IndexStore store ;
422+ if (storeType .isEmpty () || isBuiltinType (storeType )) {
423+ store = new IndexStore (indexSettings );
424+ } else {
425+ Function <IndexSettings , IndexStore > factory = indexStoreFactories .get (storeType );
426+ if (factory == null ) {
427+ throw new IllegalArgumentException ("Unknown store type [" + storeType + "]" );
428+ }
429+ store = factory .apply (indexSettings );
430+ if (store == null ) {
431+ throw new IllegalStateException ("store must not be null" );
432+ }
433+ }
434+ return store ;
435+ }
436+
378437 /**
379438 * creates a new mapper service to do administrative work like mapping updates. This *should not* be used for document parsing.
380439 * doing so will result in an exception.
0 commit comments