Skip to content

Commit 56f1753

Browse files
authored
Lucene: AnalyzerChooser no longer takes the text when choosing an analyzer (#2994)
This removes the option for having `AnalyzerChooser` pick the analyzer based on the contents of the query. This moves it so that the `FDBDirectoryManager` creates one `LuceneAnalyzerWrapper`, and preserves it for the transaction. Eventually this will allow `FDBDirectoryWrapper` to have the writer be lazy but final, but I didn't bring that change into here, isolating this to the breaking change. This Resolves #2993
1 parent 4d8ae08 commit 56f1753

27 files changed

+126
-224
lines changed

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/AnalyzerChooser.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,11 @@
2323
import org.apache.lucene.analysis.Analyzer;
2424

2525
import javax.annotation.Nonnull;
26-
import java.util.Collections;
27-
import java.util.List;
2826

2927
/**
30-
* Choose an {@link Analyzer} given texts.
28+
* Choose an {@link Analyzer}.
3129
*/
3230
public interface AnalyzerChooser {
3331
@Nonnull
34-
default LuceneAnalyzerWrapper chooseAnalyzer(@Nonnull String text) {
35-
return chooseAnalyzer(Collections.singletonList(text));
36-
}
37-
38-
@Nonnull
39-
LuceneAnalyzerWrapper chooseAnalyzer(@Nonnull List<String> texts);
32+
LuceneAnalyzerWrapper chooseAnalyzer();
4033
}

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/EmailCjkSynonymAnalyzerFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public AnalyzerChooser getIndexAnalyzerChooser(@Nonnull Index index) {
6565
final String minLengthString = Optional.ofNullable(index.getOption(IndexOptions.TEXT_TOKEN_MIN_SIZE)).orElse(DEFAULT_MINIMUM_TOKEN_LENGTH);
6666
final String maxLengthString = Optional.ofNullable(index.getOption(IndexOptions.TEXT_TOKEN_MAX_SIZE)).orElse(Integer.toString(UAX29URLEmailAnalyzer.DEFAULT_MAX_TOKEN_LENGTH));
6767

68-
return t -> new LuceneAnalyzerWrapper(UNIQUE_IDENTIFIER,
68+
return () -> new LuceneAnalyzerWrapper(UNIQUE_IDENTIFIER,
6969
new EmailCjkSynonymAnalyzer(MINIMAL_STOP_WORDS, 1, Integer.parseInt(minLengthString), Integer.parseInt(maxLengthString), true,
7070
false, null));
7171
} catch (NumberFormatException ex) {
@@ -81,7 +81,7 @@ public AnalyzerChooser getQueryAnalyzerChooser(@Nonnull Index index, @Nonnull An
8181
final String minLengthString = Optional.ofNullable(index.getOption(IndexOptions.TEXT_TOKEN_MIN_SIZE)).orElse(DEFAULT_MINIMUM_TOKEN_LENGTH);
8282
final String maxLengthString = Optional.ofNullable(index.getOption(IndexOptions.TEXT_TOKEN_MAX_SIZE)).orElse(DEFAULT_MAXIMUM_TOKEN_LENGTH);
8383
final String synonymConfigName = index.getOption(LuceneIndexOptions.TEXT_SYNONYM_SET_NAME_OPTION);
84-
return t -> new LuceneAnalyzerWrapper(UNIQUE_IDENTIFIER,
84+
return () -> new LuceneAnalyzerWrapper(UNIQUE_IDENTIFIER,
8585
new EmailCjkSynonymAnalyzer(MINIMAL_STOP_WORDS, 1, Integer.parseInt(minLengthString), Integer.parseInt(maxLengthString), true,
8686
synonymConfigName != null, synonymConfigName != null ? SynonymMapRegistryImpl.instance().getSynonymMap(synonymConfigName) : null));
8787
} catch (NumberFormatException ex) {

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/LuceneAnalyzerCombinationProvider.java

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424

2525
import javax.annotation.Nonnull;
2626
import javax.annotation.Nullable;
27-
import java.util.Collections;
28-
import java.util.List;
2927
import java.util.Map;
3028
import java.util.SortedMap;
3129
import java.util.TreeMap;
@@ -37,47 +35,39 @@
3735
* The default analyzer chooser is used for all fields of one Lucene index except the fields which has overrides in the analyzer chooser per field mapping.
3836
*/
3937
public class LuceneAnalyzerCombinationProvider {
40-
public static final String DELINEATOR_BETWEEN_KEY_AND_VALUE = ":";
4138

42-
public static final String DELINEATOR_BETWEEN_KEY_VALUE_PAIRS = ",";
43-
private AnalyzerChooser defaultIndexAnalyzerChooser;
44-
private AnalyzerChooser defaultQueryAnalyzerChooser;
45-
private Map<String, AnalyzerChooser> indexAnalyzerChooserPerFieldOverride;
46-
private Map<String, AnalyzerChooser> queryAnalyzerChooserPerFieldOverride;
39+
@Nonnull
40+
private final LuceneAnalyzerWrapper indexAnalyzerWrapper;
41+
@Nonnull
42+
private final LuceneAnalyzerWrapper queryAnalyzerWrapper;
4743

48-
public LuceneAnalyzerCombinationProvider(@Nonnull AnalyzerChooser defaultIndexAnalyzerChooser, @Nonnull AnalyzerChooser defaultQueryAnalyzerChooser,
49-
@Nullable Map<String, AnalyzerChooser> indexAnalyzerChooserPerFieldOverride, @Nullable Map<String, AnalyzerChooser> queryAnalyzerChooserPerFieldOverride) {
50-
this.defaultIndexAnalyzerChooser = defaultIndexAnalyzerChooser;
51-
this.defaultQueryAnalyzerChooser = defaultQueryAnalyzerChooser;
52-
this.indexAnalyzerChooserPerFieldOverride = indexAnalyzerChooserPerFieldOverride;
53-
this.queryAnalyzerChooserPerFieldOverride = queryAnalyzerChooserPerFieldOverride;
44+
public LuceneAnalyzerCombinationProvider(@Nonnull AnalyzerChooser defaultIndexAnalyzerChooser,
45+
@Nonnull AnalyzerChooser defaultQueryAnalyzerChooser,
46+
@Nullable Map<String, AnalyzerChooser> indexAnalyzerChooserPerFieldOverride,
47+
@Nullable Map<String, AnalyzerChooser> queryAnalyzerChooserPerFieldOverride) {
48+
indexAnalyzerWrapper = buildAnalyzerWrapper(defaultIndexAnalyzerChooser, indexAnalyzerChooserPerFieldOverride);
49+
queryAnalyzerWrapper = buildAnalyzerWrapper(defaultQueryAnalyzerChooser, queryAnalyzerChooserPerFieldOverride);
5450
}
5551

56-
public LuceneAnalyzerWrapper provideIndexAnalyzer(@Nonnull String text) {
57-
return provideIndexAnalyzer(Collections.singletonList(text));
52+
@Nonnull
53+
public LuceneAnalyzerWrapper provideIndexAnalyzer() {
54+
return indexAnalyzerWrapper;
5855
}
5956

60-
public LuceneAnalyzerWrapper provideIndexAnalyzer(@Nonnull List<String> texts) {
61-
return buildAnalyzerWrapper(texts, defaultIndexAnalyzerChooser, indexAnalyzerChooserPerFieldOverride);
62-
}
63-
64-
public LuceneAnalyzerWrapper provideQueryAnalyzer(@Nonnull String text) {
65-
return provideQueryAnalyzer(Collections.singletonList(text));
66-
}
67-
68-
public LuceneAnalyzerWrapper provideQueryAnalyzer(@Nonnull List<String> texts) {
69-
return buildAnalyzerWrapper(texts, defaultQueryAnalyzerChooser, queryAnalyzerChooserPerFieldOverride);
57+
@Nonnull
58+
public LuceneAnalyzerWrapper provideQueryAnalyzer() {
59+
return queryAnalyzerWrapper;
7060
}
7161

62+
@Nonnull
7263
@SuppressWarnings("PMD.CloseResource")
73-
private static LuceneAnalyzerWrapper buildAnalyzerWrapper(@Nonnull List<String> texts,
74-
@Nonnull AnalyzerChooser defaultAnalyzerChooser,
64+
private static LuceneAnalyzerWrapper buildAnalyzerWrapper(@Nonnull AnalyzerChooser defaultAnalyzerChooser,
7565
@Nullable Map<String, AnalyzerChooser> customizedAnalyzerChooserPerField) {
76-
final LuceneAnalyzerWrapper defaultAnalyzerWrapper = defaultAnalyzerChooser.chooseAnalyzer(texts);
66+
final LuceneAnalyzerWrapper defaultAnalyzerWrapper = defaultAnalyzerChooser.chooseAnalyzer();
7767
if (customizedAnalyzerChooserPerField != null) {
7868
// The order of keys matters because the identifier for each map needs to be consistent
7969
SortedMap<String, LuceneAnalyzerWrapper> analyzerWrapperMap = new TreeMap<>(customizedAnalyzerChooserPerField.entrySet().stream()
80-
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().chooseAnalyzer(texts))));
70+
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().chooseAnalyzer())));
8171

8272
PerFieldAnalyzerWrapper analyzerWrapper = new PerFieldAnalyzerWrapper(defaultAnalyzerWrapper.getAnalyzer(),
8373
analyzerWrapperMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getAnalyzer())));

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/LuceneAnalyzerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ public interface LuceneAnalyzerFactory {
7575
*/
7676
@Nonnull
7777
default AnalyzerChooser getQueryAnalyzerChooser(@Nonnull Index index, @Nonnull AnalyzerChooser indexAnalyzerChooser) {
78-
return t -> LuceneAnalyzerWrapper.getStandardAnalyzerWrapper();
78+
return LuceneAnalyzerWrapper::getStandardAnalyzerWrapper;
7979
}
8080
}

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/LuceneAnalyzerRegistryImpl.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import com.apple.foundationdb.record.metadata.Index;
2727
import com.apple.foundationdb.record.metadata.MetaDataException;
2828
import com.apple.foundationdb.record.util.ServiceLoaderProvider;
29-
import com.apple.foundationdb.record.util.pair.Pair;
29+
import com.apple.foundationdb.record.util.pair.NonnullPair;
3030
import org.slf4j.Logger;
3131
import org.slf4j.LoggerFactory;
3232

@@ -96,14 +96,14 @@ public LuceneAnalyzerCombinationProvider getLuceneAnalyzerCombinationProvider(@N
9696
@Nonnull final Map<String, LuceneIndexExpressions.DocumentFieldDerivation> auxiliaryFieldInfo) {
9797
final String defaultAnalyzerName = index.getOption(type.getAnalyzerOptionKey());
9898
final String analyzerPerFieldName = index.getOption(type.getAnalyzerPerFieldOptionKey());
99-
Pair<AnalyzerChooser, AnalyzerChooser> defaultAnalyzerChooserPair = getAnalyzerChooser(index, defaultAnalyzerName, type);
99+
NonnullPair<AnalyzerChooser, AnalyzerChooser> defaultAnalyzerChooserPair = getAnalyzerChooser(index, defaultAnalyzerName, type);
100100

101101
Map<String, AnalyzerChooser> indexAnalyzerChooserPerFieldOverride = new TreeMap<>();
102102
Map<String, AnalyzerChooser> queryAnalyzerChooserPerFieldOverride = new TreeMap<>();
103103

104104
if (analyzerPerFieldName != null) {
105105
LuceneIndexOptions.parseKeyValuePairOptionValue(analyzerPerFieldName).forEach((fieldName, analyzerName) -> {
106-
Pair<AnalyzerChooser, AnalyzerChooser> perFieldAnalyzerChooserPair = getAnalyzerChooser(index, analyzerName, type);
106+
NonnullPair<AnalyzerChooser, AnalyzerChooser> perFieldAnalyzerChooserPair = getAnalyzerChooser(index, analyzerName, type);
107107
indexAnalyzerChooserPerFieldOverride.put(fieldName, perFieldAnalyzerChooserPair.getLeft());
108108
queryAnalyzerChooserPerFieldOverride.put(fieldName, perFieldAnalyzerChooserPair.getRight());
109109
});
@@ -145,11 +145,11 @@ private static boolean isEligibleForNoOpAnalyzer(@Nonnull final LuceneIndexExpre
145145
return fieldInfo.getType() != LuceneIndexExpressions.DocumentFieldType.TEXT;
146146
}
147147

148-
private Pair<AnalyzerChooser, AnalyzerChooser> getAnalyzerChooser(@Nonnull Index index, @Nullable String analyzerName, @Nonnull LuceneAnalyzerType type) {
148+
private NonnullPair<AnalyzerChooser, AnalyzerChooser> getAnalyzerChooser(@Nonnull Index index, @Nullable String analyzerName, @Nonnull LuceneAnalyzerType type) {
149149
final Map<String, LuceneAnalyzerFactory> registryForType = Objects.requireNonNullElse(registry.get(type), Collections.emptyMap());
150150
if (analyzerName == null || !registryForType.containsKey(analyzerName)) {
151-
return Pair.of(t -> LuceneAnalyzerWrapper.getStandardAnalyzerWrapper(),
152-
t -> LuceneAnalyzerWrapper.getStandardAnalyzerWrapper());
151+
return NonnullPair.of(LuceneAnalyzerWrapper::getStandardAnalyzerWrapper,
152+
LuceneAnalyzerWrapper::getStandardAnalyzerWrapper);
153153
} else {
154154
LuceneAnalyzerFactory analyzerFactory = registryForType.get(analyzerName);
155155
if (analyzerFactory == null) {
@@ -158,7 +158,7 @@ private Pair<AnalyzerChooser, AnalyzerChooser> getAnalyzerChooser(@Nonnull Index
158158
LuceneLogMessageKeys.ANALYZER_TYPE, type.name());
159159
}
160160
final AnalyzerChooser indexAnalyzerChooser = analyzerFactory.getIndexAnalyzerChooser(index);
161-
return Pair.of(indexAnalyzerChooser, analyzerFactory.getQueryAnalyzerChooser(index, indexAnalyzerChooser));
161+
return NonnullPair.of(indexAnalyzerChooser, analyzerFactory.getQueryAnalyzerChooser(index, indexAnalyzerChooser));
162162
}
163163
}
164164
}

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/LuceneAutoCompleteAnalyzerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ public LuceneAnalyzerType getType() {
4848
@Nonnull
4949
@Override
5050
public AnalyzerChooser getIndexAnalyzerChooser(@Nonnull Index index) {
51-
return t -> LuceneAnalyzerWrapper.getStandardAnalyzerWrapper();
51+
return LuceneAnalyzerWrapper::getStandardAnalyzerWrapper;
5252
}
5353
}

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/LuceneAutoCompleteQueryClause.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,12 @@ public BoundQuery bind(@Nonnull FDBRecordStoreBase<?> store, @Nonnull Index inde
122122
final Map<String, PointsConfig> pointsConfigMap = LuceneIndexExpressions.constructPointConfigMap(store, index);
123123
LuceneQueryParserFactory parserFactory = LuceneQueryParserFactoryProvider.instance().getParserFactory();
124124
final QueryParser parser = parserFactory.createMultiFieldQueryParser(fields.toArray(new String[0]),
125-
analyzerSelector.provideIndexAnalyzer(searchKey).getAnalyzer(), pointsConfigMap);
125+
analyzerSelector.provideIndexAnalyzer().getAnalyzer(), pointsConfigMap);
126126

127127

128-
final var finalQuery = phraseQueryNeeded
129-
? buildQueryForPhraseMatching(parser, fields, searchKey)
130-
: buildQueryForTermsMatching(analyzerSelector.provideIndexAnalyzer(searchKey).getAnalyzer(), fields, searchKey);
128+
final Query finalQuery = phraseQueryNeeded
129+
? buildQueryForPhraseMatching(parser, fields, searchKey)
130+
: buildQueryForTermsMatching(analyzerSelector.provideIndexAnalyzer().getAnalyzer(), fields, searchKey);
131131
if (LOGGER.isDebugEnabled()) {
132132
LOGGER.debug(KeyValueLogMessage.build("query for auto-complete")
133133
.addKeyAndValue(LogMessageKeys.INDEX_NAME, index.getName())

fdb-record-layer-lucene/src/main/java/com/apple/foundationdb/record/lucene/LuceneIndexMaintainer.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ public class LuceneIndexMaintainer extends StandardIndexMaintainer {
114114

115115
@Nonnull
116116
private final FDBDirectoryManager directoryManager;
117-
private final LuceneAnalyzerCombinationProvider indexAnalyzerSelector;
118117
private final LuceneAnalyzerCombinationProvider autoCompleteAnalyzerSelector;
119118
public static final String PRIMARY_KEY_FIELD_NAME = "_p";
120119
protected static final String PRIMARY_KEY_SEARCH_NAME = "_s";
@@ -130,7 +129,6 @@ public LuceneIndexMaintainer(@Nonnull final IndexMaintainerState state, @Nonnull
130129
this.executor = executor;
131130
this.directoryManager = createDirectoryManager(state);
132131
final var fieldInfos = LuceneIndexExpressions.getDocumentFieldDerivations(state.index, state.store.getRecordMetaData());
133-
this.indexAnalyzerSelector = LuceneAnalyzerRegistryImpl.instance().getLuceneAnalyzerCombinationProvider(state.index, LuceneAnalyzerType.FULL_TEXT, fieldInfos);
134132
this.autoCompleteAnalyzerSelector = LuceneAnalyzerRegistryImpl.instance().getLuceneAnalyzerCombinationProvider(state.index, LuceneAnalyzerType.AUTO_COMPLETE, fieldInfos);
135133
String formatString = state.index.getOption(LuceneIndexOptions.PRIMARY_KEY_SERIALIZATION_FORMAT);
136134
keySerializer = LuceneIndexKeySerializer.fromStringFormat(formatString);
@@ -177,7 +175,7 @@ public RecordCursor<IndexEntry> scan(@Nonnull final IndexScanBounds scanBounds,
177175
state.context.getPropertyStorage().getPropertyValue(LuceneRecordContextProperties.LUCENE_INDEX_CURSOR_PAGE_SIZE),
178176
scanProperties, state, scanQuery.getQuery(), scanQuery.getSort(), continuation,
179177
scanQuery.getGroupKey(), partitionInfo, scanQuery.getLuceneQueryHighlightParameters(), scanQuery.getTermMap(),
180-
scanQuery.getStoredFields(), scanQuery.getStoredFieldTypes(), indexAnalyzerSelector, autoCompleteAnalyzerSelector);
178+
scanQuery.getStoredFields(), scanQuery.getStoredFieldTypes(), directoryManager.getAnalyzerSelector(), autoCompleteAnalyzerSelector);
181179
}
182180

183181
if (scanType.equals(LuceneScanTypes.BY_LUCENE_SPELL_CHECK)) {
@@ -186,7 +184,8 @@ public RecordCursor<IndexEntry> scan(@Nonnull final IndexScanBounds scanBounds,
186184
}
187185
LuceneScanSpellCheck scanSpellcheck = (LuceneScanSpellCheck)scanBounds;
188186
return new LuceneSpellCheckRecordCursor(scanSpellcheck.getFields(), scanSpellcheck.getWord(),
189-
executor, scanProperties, state, scanSpellcheck.getGroupKey(), partitioner.selectQueryPartitionId(scanSpellcheck.getGroupKey()));
187+
executor, scanProperties, state, scanSpellcheck.getGroupKey(),
188+
partitioner.selectQueryPartitionId(scanSpellcheck.getGroupKey()));
190189
}
191190

192191
throw new RecordCoreException("unsupported scan type for Lucene index: " + scanType);
@@ -253,11 +252,8 @@ private void writeDocument(@Nonnull List<LuceneDocumentFromRecord.DocumentField>
253252
Integer partitionId,
254253
Tuple primaryKey) throws IOException {
255254
final long startTime = System.nanoTime();
256-
final List<String> texts = fields.stream()
257-
.filter(f -> f.getType().equals(LuceneIndexExpressions.DocumentFieldType.TEXT))
258-
.map(f -> (String) f.getValue()).collect(Collectors.toList());
259255
Document document = new Document();
260-
final IndexWriter newWriter = directoryManager.getIndexWriter(groupingKey, partitionId, indexAnalyzerSelector.provideIndexAnalyzer(texts));
256+
final IndexWriter newWriter = directoryManager.getIndexWriter(groupingKey, partitionId);
261257

262258
BytesRef ref = new BytesRef(keySerializer.asPackedByteArray(primaryKey));
263259
// use packed Tuple for the Stored and Sorted fields
@@ -299,7 +295,7 @@ private Map<IndexOptions, List<LuceneDocumentFromRecord.DocumentField>> getIndex
299295
@SuppressWarnings({"PMD.CloseResource", "java:S2095"})
300296
int deleteDocument(Tuple groupingKey, Integer partitionId, Tuple primaryKey) throws IOException {
301297
final long startTime = System.nanoTime();
302-
final IndexWriter indexWriter = directoryManager.getIndexWriter(groupingKey, partitionId, indexAnalyzerSelector.provideIndexAnalyzer(""));
298+
final IndexWriter indexWriter = directoryManager.getIndexWriter(groupingKey, partitionId);
303299
@Nullable final LucenePrimaryKeySegmentIndex segmentIndex = directoryManager.getDirectory(groupingKey, partitionId).getPrimaryKeySegmentIndex();
304300

305301
if (segmentIndex != null) {
@@ -360,16 +356,15 @@ public CompletableFuture<Void> mergeIndex() {
360356
return rebalancePartitions()
361357
.thenCompose(ignored -> {
362358
state.store.getIndexDeferredMaintenanceControl().setLastStep(IndexDeferredMaintenanceControl.LastStep.MERGE);
363-
return directoryManager.mergeIndex(partitioner, indexAnalyzerSelector.provideIndexAnalyzer(""));
359+
return directoryManager.mergeIndex(partitioner);
364360
});
365361
}
366362

367363
@VisibleForTesting
368364
public void mergeIndexForTesting(@Nonnull final Tuple groupingKey,
369365
@Nullable final Integer partitionId,
370366
@Nonnull final AgilityContext agilityContext) throws IOException {
371-
directoryManager.mergeIndexWithContext(indexAnalyzerSelector.provideIndexAnalyzer(""),
372-
groupingKey, partitionId, agilityContext);
367+
directoryManager.mergeIndexWithContext(groupingKey, partitionId, agilityContext);
373368
}
374369

375370
@Nonnull
@@ -761,7 +756,7 @@ public IndexScrubbingTools<?> getIndexScrubbingTools(final IndexScrubbingTools.S
761756
final Map<String, String> options = state.index.getOptions();
762757
if (Boolean.parseBoolean(options.get(LuceneIndexOptions.PRIMARY_KEY_SEGMENT_INDEX_ENABLED)) ||
763758
Boolean.parseBoolean(options.get(LuceneIndexOptions.PRIMARY_KEY_SEGMENT_INDEX_V2_ENABLED))) {
764-
return new LuceneIndexScrubbingToolsMissing(partitioner, directoryManager, indexAnalyzerSelector);
759+
return new LuceneIndexScrubbingToolsMissing(partitioner, directoryManager);
765760
}
766761
return null;
767762
default:

0 commit comments

Comments
 (0)