blob: b306b53109e8b73ca4bb7813590a3c395e8ddc69 [file] [log] [blame]
package org.apache.nifi.pql.evaluation.order;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.nifi.pql.evaluation.OperandEvaluator;
import org.apache.nifi.pql.groups.Group;
import org.apache.nifi.provenance.ProvenanceEventRecord;
public class FieldSorter implements RowSorter {
private final SortedSet<CellValue<ProvenanceEventRecord>> values = new TreeSet<>();
private final MultiFieldComparator comparator;
public FieldSorter(final Map<OperandEvaluator<?>, SortDirection> fieldEvaluators) {
comparator = new MultiFieldComparator(fieldEvaluators);
}
@Override
public void add(final ProvenanceEventRecord record, final Group group, final int rowId) {
values.add(new CellValue<ProvenanceEventRecord>(record, rowId, comparator));
}
@Override
public List<Integer> sort() {
final List<Integer> rowIds = new ArrayList<>();
for ( final CellValue<?> value : values ) {
rowIds.add( value.getRowId() );
}
return rowIds;
}
private static class MultiFieldComparator implements Comparator<ProvenanceEventRecord> {
private final Map<OperandEvaluator<?>, SortDirection> evals;
private final Comparator<Number> numberComparator = Sorters.newNumberComparator();
private final Comparator<Object> objectComparator = Sorters.newObjectComparator();
public MultiFieldComparator(final Map<OperandEvaluator<?>, SortDirection> evals) {
this.evals = evals;
}
@Override
public int compare(final ProvenanceEventRecord r1, final ProvenanceEventRecord r2) {
if ( r1 == r2 ) {
return 0;
}
if (r1 == null && r2 == null) {
return 0;
}
if (r1 == null) {
return -1;
}
if (r2 == null) {
return 1;
}
for ( final Map.Entry<OperandEvaluator<?>, SortDirection> entry : evals.entrySet() ) {
final OperandEvaluator<?> eval = entry.getKey();
final SortDirection dir = entry.getValue();
int comparisonResult;
final Object v1 = eval.evaluate(r1);
final Object v2 = eval.evaluate(r2);
if ( Number.class.isAssignableFrom(eval.getType()) ) {
comparisonResult = numberComparator.compare((Number) v1, (Number) v2);
} else {
comparisonResult = objectComparator.compare(v1, v2);
}
if ( comparisonResult != 0 ) {
return dir == SortDirection.ASC ? comparisonResult : -comparisonResult;
}
}
return 0;
}
}
}