CavalliumDBEngine/src/main/java/it/cavallium/dbengine/lucene/LMDBComparator.java

120 lines
5.4 KiB
Java

package it.cavallium.dbengine.lucene;
import static org.apache.lucene.search.SortField.STRING_LAST;
import it.cavallium.dbengine.database.disk.LLTempLMDBEnv;
import it.cavallium.dbengine.lucene.comparators.DocComparator;
import it.cavallium.dbengine.lucene.comparators.DoubleComparator;
import it.cavallium.dbengine.lucene.comparators.FloatComparator;
import it.cavallium.dbengine.lucene.comparators.IntComparator;
import it.cavallium.dbengine.lucene.comparators.LongComparator;
import it.cavallium.dbengine.lucene.comparators.RelevanceComparator;
import it.cavallium.dbengine.lucene.comparators.TermOrdValComparator;
import java.io.IOException;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.LeafFieldComparator;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
import org.apache.lucene.search.SortedNumericSortField;
public class LMDBComparator {
public static FieldComparator<?> getComparator(LLTempLMDBEnv env, SortField sortField,
int numHits, int sortPos) {
var sortFieldClass = sortField.getClass();
if (sortFieldClass == org.apache.lucene.search.SortedNumericSortField.class) {
var nf = (org.apache.lucene.search.SortedNumericSortField) sortField;
var type = nf.getNumericType();
var missingValue = nf.getMissingValue();
var reverse = nf.getReverse();
var selector = nf.getSelector();
final FieldComparator<?> fieldComparator = switch (type) {
case INT -> new IntComparator(env, numHits, nf.getField(), (Integer) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new IntLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field)
throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
case FLOAT -> new FloatComparator(env, numHits, nf.getField(), (Float) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new FloatLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field)
throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
case LONG -> new LongComparator(env, numHits, nf.getField(), (Long) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new LongLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field)
throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
case DOUBLE -> new DoubleComparator(env, numHits, nf.getField(), (Double) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new DoubleLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field)
throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
case CUSTOM, DOC, REWRITEABLE, STRING_VAL, SCORE, STRING -> throw new AssertionError();
};
if (!nf.getOptimizeSortWithPoints()) {
fieldComparator.disableSkipping();
}
return fieldComparator;
} else if (sortFieldClass == SortField.class) {
var missingValue = sortField.getMissingValue();
var reverse = sortField.getReverse();
var field = sortField.getField();
var comparatorSource = sortField.getComparatorSource();
return switch (sortField.getType()) {
case SCORE -> new RelevanceComparator(env, numHits);
case DOC -> new DocComparator(env, numHits, reverse, sortPos);
case INT -> new IntComparator(env, numHits, field, (Integer) missingValue,
reverse, sortPos);
case FLOAT -> new FloatComparator(env, numHits, field, (Float) missingValue,
reverse, sortPos);
case LONG -> new LongComparator(env, numHits, field, (Long) missingValue,
reverse, sortPos);
case DOUBLE -> new DoubleComparator(env, numHits, field, (Double) missingValue,
reverse, sortPos);
case CUSTOM -> {
assert comparatorSource != null;
yield comparatorSource.newComparator(field, numHits, sortPos, reverse);
}
case STRING -> new TermOrdValComparator(env, numHits, field, missingValue == STRING_LAST);
case STRING_VAL -> throw new NotImplementedException("String val sort field not implemented");
case REWRITEABLE -> throw new IllegalStateException(
"SortField needs to be rewritten through Sort.rewrite(..) and SortField.rewrite(..)");
};
} else {
throw new NotImplementedException("SortField type not implemented: " + sortFieldClass.getName());
}
}
}