com.bigdata.bop.solutions.BindingSetComparator Maven / Gradle / Ivy
package com.bigdata.bop.solutions;
import java.util.Comparator;
import com.bigdata.bop.IBind;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.IValueExpression;
/**
* A comparator for binding sets.
*/
public class BindingSetComparator implements Comparator {
/**
* The sort order to be imposed.
*/
private final ISortOrder[] sortOrder;
/**
* The comparison to use on the values in the binding sets.
*/
private final Comparator valueComparator;
/** The #of solutions compared. */
private long n = 0;
/**
*
* @param sortOrder
* The sort order to be imposed. While the {@link ISortOrder} is
* defined in terms of {@link IValueExpression}s, any
* {@link IValueExpression}s MUST be either bare variables or
* constants or be {@link IBind}s where the nested
* {@link IValueExpression} has been computed and bound on the
* solutions to be compared by the caller.
* @param valueComparator
* The comparator used on the values extracted from the
* {@link IBindingSet}s.
*/
public BindingSetComparator(final ISortOrder[] sortOrder,
final Comparator valueComparator) {
if (sortOrder == null)
throw new IllegalArgumentException();
if (sortOrder.length == 0)
throw new IllegalArgumentException();
if(valueComparator == null)
throw new IllegalArgumentException();
this.sortOrder = sortOrder;
this.valueComparator = valueComparator;
}
@Override
public int compare(final IBindingSet bs1, final IBindingSet bs2) {
if ((n++ % 1000) == 1) {
/*
* Check for interrupts, but not too often.
*/
if (Thread.interrupted())
throw new RuntimeException(new InterruptedException());
}
for (int i = 0; i < sortOrder.length; i++) {
final ISortOrder o = sortOrder[i];
IValueExpression v = o.getExpr();
if (v instanceof IBind>) {
/*
* Use the variable on which the computed expression was bound.
*
* Note: This assumes that the value expression for the bind has
* already been evaluated such that we may simply resolve the
* bound value for the variable against the binding set. This is
* necessary to avoid recomputing the value expression each time
* we encounter a given binding set. Since we are sorting, we
* could see the same binding set many, many times while the
* sort figures out its position in the total ordering. The
* top-level ORDER BY operator is responsible for evaluating
* those value expressions when it buffers its solution set for
* the sort.
*/
v = ((IBind) v).getVar();
}
/*
* Note: This wind up invoking the comparison on IVs. When comparing
* IVs which are not inline values, the IVs MUST have been
* materialized before the comparator may be applied.
*/
int ret = valueComparator.compare(v.get(bs1), v.get(bs2));
if (!o.isAscending())
ret = -ret;
if (ret != 0) {
// Not equal for this variable.
return ret;
}
}
// equal for all variables.
return 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy