blob: e4db8da09772b080f698668e033b6b7fe18a5b7e [file] [log] [blame]
package edu.uci.ics.asterix.formats.nontagged;
import java.io.Serializable;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ADateTimeAscBinaryComparatorFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.AObjectAscBinaryComparatorFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.AObjectDescBinaryComparatorFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.BooleanBinaryComparatorFactory;
import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.RectangleBinaryComparatorFactory;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
import edu.uci.ics.hyracks.algebricks.data.IBinaryComparatorFactoryProvider;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryComparatorFactory;
import edu.uci.ics.hyracks.data.std.primitive.BytePointable;
import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
import edu.uci.ics.hyracks.data.std.primitive.FloatPointable;
import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
import edu.uci.ics.hyracks.data.std.primitive.LongPointable;
import edu.uci.ics.hyracks.data.std.primitive.ShortPointable;
import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
public class AqlBinaryComparatorFactoryProvider implements IBinaryComparatorFactoryProvider, Serializable {
private static final long serialVersionUID = 1L;
public static final AqlBinaryComparatorFactoryProvider INSTANCE = new AqlBinaryComparatorFactoryProvider();
public static final PointableBinaryComparatorFactory BYTE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
BytePointable.FACTORY);
public static final PointableBinaryComparatorFactory SHORT_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
ShortPointable.FACTORY);
public static final PointableBinaryComparatorFactory INTEGER_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
IntegerPointable.FACTORY);
public static final PointableBinaryComparatorFactory LONG_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
LongPointable.FACTORY);
public static final PointableBinaryComparatorFactory FLOAT_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
FloatPointable.FACTORY);
public static final PointableBinaryComparatorFactory DOUBLE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
DoublePointable.FACTORY);
public static final PointableBinaryComparatorFactory UTF8STRING_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
UTF8StringPointable.FACTORY);
// Equivalent to UTF8STRING_POINTABLE_INSTANCE but all characters are considered lower case to implement case-insensitive comparisons.
public static final PointableBinaryComparatorFactory UTF8STRING_LOWERCASE_POINTABLE_INSTANCE = new PointableBinaryComparatorFactory(
UTF8StringLowercasePointable.FACTORY);
private AqlBinaryComparatorFactoryProvider() {
}
// This method add the option of ignoring the case in string comparisons.
// TODO: We should incorporate this option more nicely, but I'd have to change algebricks.
public IBinaryComparatorFactory getBinaryComparatorFactory(Object type, boolean ascending, boolean ignoreCase) {
if (type == null) {
return anyBinaryComparatorFactory(ascending);
}
IAType aqlType = (IAType) type;
if (aqlType.getTypeTag() == ATypeTag.STRING && ignoreCase) {
return addOffset(UTF8STRING_LOWERCASE_POINTABLE_INSTANCE, ascending);
}
return getBinaryComparatorFactory(type, ascending);
}
@Override
public IBinaryComparatorFactory getBinaryComparatorFactory(Object type, boolean ascending) {
if (type == null) {
return anyBinaryComparatorFactory(ascending);
}
IAType aqlType = (IAType) type;
return getBinaryComparatorFactory(aqlType.getTypeTag(), ascending);
}
public IBinaryComparatorFactory getBinaryComparatorFactory(ATypeTag type, boolean ascending) {
switch (type) {
case ANY:
case UNION: { // we could do smth better for nullable fields
return anyBinaryComparatorFactory(ascending);
}
case NULL: {
return new IBinaryComparatorFactory() {
private static final long serialVersionUID = 1L;
@Override
public IBinaryComparator createBinaryComparator() {
return new IBinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return 0;
}
};
}
};
}
case BOOLEAN: {
return addOffset(BooleanBinaryComparatorFactory.INSTANCE, ascending);
}
case INT8: {
return addOffset(BYTE_POINTABLE_INSTANCE, ascending);
}
case INT16: {
return addOffset(SHORT_POINTABLE_INSTANCE, ascending);
}
case INT32: {
return addOffset(INTEGER_POINTABLE_INSTANCE, ascending);
}
case INT64: {
return addOffset(LONG_POINTABLE_INSTANCE, ascending);
}
case FLOAT: {
return addOffset(FLOAT_POINTABLE_INSTANCE, ascending);
}
case DOUBLE: {
return addOffset(DOUBLE_POINTABLE_INSTANCE, ascending);
}
case STRING: {
return addOffset(UTF8STRING_POINTABLE_INSTANCE, ascending);
}
case RECTANGLE: {
return addOffset(RectangleBinaryComparatorFactory.INSTANCE, ascending);
}
case DATE:
case TIME:
case DATETIME: {
return addOffset(ADateTimeAscBinaryComparatorFactory.INSTANCE, ascending);
}
default: {
throw new NotImplementedException("No binary comparator factory implemented for type "
+ type + " .");
}
}
}
private IBinaryComparatorFactory addOffset(final IBinaryComparatorFactory inst, final boolean ascending) {
return new IBinaryComparatorFactory() {
private static final long serialVersionUID = 1L;
@Override
public IBinaryComparator createBinaryComparator() {
final IBinaryComparator bc = inst.createBinaryComparator();
if (ascending) {
return new IBinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
} else {
return new IBinaryComparator() {
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return -bc.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
}
};
}
}
};
}
private IBinaryComparatorFactory anyBinaryComparatorFactory(boolean ascending) {
if (ascending) {
return AObjectAscBinaryComparatorFactory.INSTANCE;
} else {
return AObjectDescBinaryComparatorFactory.INSTANCE;
}
}
}