Search in sources :

Example 1 with PointableBinaryComparatorFactory

use of org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory in project asterixdb by apache.

the class AObjectAscBinaryComparatorFactory method createBinaryComparator.

@Override
public IBinaryComparator createBinaryComparator() {
    return new ABinaryComparator() {

        // a storage to promote a value
        private ArrayBackedValueStorage castBuffer = new ArrayBackedValueStorage();

        private ITypeConvertComputer promoteComputer;

        // BOOLEAN
        final IBinaryComparator ascBoolComp = BooleanBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // TINYINT
        final IBinaryComparator ascByteComp = new PointableBinaryComparatorFactory(BytePointable.FACTORY).createBinaryComparator();

        // SMALLINT
        final IBinaryComparator ascShortComp = new PointableBinaryComparatorFactory(ShortPointable.FACTORY).createBinaryComparator();

        // INTEGER
        final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY).createBinaryComparator();

        // BIGINT
        final IBinaryComparator ascLongComp = LongBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // STRING
        final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY).createBinaryComparator();

        // BINARY
        final IBinaryComparator ascByteArrayComp = new PointableBinaryComparatorFactory(ByteArrayPointable.FACTORY).createBinaryComparator();

        // FLOAT
        final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY).createBinaryComparator();

        // DOUBLE
        final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY).createBinaryComparator();

        // RECTANGLE
        final IBinaryComparator ascRectangleComp = ARectanglePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // CIRCLE
        final IBinaryComparator ascCircleComp = ACirclePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // DURATION
        final IBinaryComparator ascDurationComp = ADurationPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // INTERVAL
        final IBinaryComparator ascIntervalComp = AIntervalAscPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // LINE
        final IBinaryComparator ascLineComp = ALinePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // POINT
        final IBinaryComparator ascPointComp = APointPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // POINT3D
        final IBinaryComparator ascPoint3DComp = APoint3DPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // POLYGON
        final IBinaryComparator ascPolygonComp = APolygonPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // UUID
        final IBinaryComparator ascUUIDComp = AUUIDPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        // RAW
        final IBinaryComparator rawComp = RawBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        @Override
        public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) throws HyracksDataException {
            // Therefore, inside this method, we return an order between two values even if one value is MISSING.
            if (b1[s1] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
                return b2[s2] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG ? 0 : -1;
            } else {
                if (b2[s2] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
                    return 1;
                }
            }
            // Therefore, inside this method, we return an order between two values even if one value is NULL.
            if (b1[s1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                return b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG ? 0 : -1;
            } else {
                if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                    return 1;
                }
            }
            ATypeTag tag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b1[s1]);
            ATypeTag tag2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b2[s2]);
            // And, we don't need to continue. We just compare raw byte by byte.
            if (tag1 == null || tag2 == null) {
                return rawComp.compare(b1, s1, l1, b2, s2, l2);
            }
            // If two type does not match, we identify the source and the target and
            // promote the source to the target type if they are compatible.
            ATypeTag sourceTypeTag = null;
            ATypeTag targetTypeTag = null;
            boolean areTwoTagsEqual = false;
            boolean typePromotionApplied = false;
            boolean leftValueChanged = false;
            if (tag1 != tag2) {
                // tag1 can be promoted to tag2 (e.g. tag1: SMALLINT, tag2: INTEGER)
                if (ATypeHierarchy.canPromote(tag1, tag2)) {
                    sourceTypeTag = tag1;
                    targetTypeTag = tag2;
                    typePromotionApplied = true;
                    leftValueChanged = true;
                // or tag2 can be promoted to tag1 (e.g. tag2: INTEGER, tag1: DOUBLE)
                } else if (ATypeHierarchy.canPromote(tag2, tag1)) {
                    sourceTypeTag = tag2;
                    targetTypeTag = tag1;
                    typePromotionApplied = true;
                }
                // we promote the source to the target by using a promoteComputer
                if (typePromotionApplied) {
                    castBuffer.reset();
                    promoteComputer = ATypeHierarchy.getTypePromoteComputer(sourceTypeTag, targetTypeTag);
                    if (promoteComputer != null) {
                        try {
                            if (leftValueChanged) {
                                // left side is the source
                                promoteComputer.convertType(b1, s1 + 1, l1 - 1, castBuffer.getDataOutput());
                            } else {
                                // right side is the source
                                promoteComputer.convertType(b2, s2 + 1, l2 - 1, castBuffer.getDataOutput());
                            }
                        } catch (IOException e) {
                            throw new HyracksDataException("ComparatorFactory - failed to promote the type:" + sourceTypeTag + " to the type:" + targetTypeTag);
                        }
                    } else {
                        // No appropriate typePromoteComputer.
                        throw new HyracksDataException("No appropriate typePromoteComputer exists for " + sourceTypeTag + " to the " + targetTypeTag + " type. Please check the code.");
                    }
                }
            } else {
                // tag1 == tag2.
                sourceTypeTag = tag1;
                targetTypeTag = tag1;
                areTwoTagsEqual = true;
            }
            // This is especially useful when we need to generate some order between any two types.
            if ((!areTwoTagsEqual && !typePromotionApplied)) {
                return rawComp.compare(b1, s1, l1, b2, s2, l2);
            }
            // Conduct actual compare()
            switch(targetTypeTag) {
                case UUID:
                    return ascUUIDComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                case BOOLEAN:
                    {
                        return ascBoolComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case TINYINT:
                    {
                        // No type promotion from another type to the TINYINT can happen
                        return ascByteComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case SMALLINT:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascShortComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascShortComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascShortComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case TIME:
                case DATE:
                case YEARMONTHDURATION:
                case INTEGER:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascIntComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascIntComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascIntComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case DATETIME:
                case DAYTIMEDURATION:
                case BIGINT:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascLongComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascLongComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascLongComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case FLOAT:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascFloatComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascFloatComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascFloatComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case DOUBLE:
                    {
                        if (!typePromotionApplied) {
                            // No type promotion case
                            return ascDoubleComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                        } else if (leftValueChanged) {
                            // Type promotion happened. Left side was the source
                            return ascDoubleComp.compare(castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1, b2, s2 + 1, l2 - 1);
                        } else {
                            // Type promotion happened. Right side was the source
                            return ascDoubleComp.compare(b1, s1 + 1, l1 - 1, castBuffer.getByteArray(), castBuffer.getStartOffset() + 1, castBuffer.getLength() - 1);
                        }
                    }
                case STRING:
                    {
                        return ascStrComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case RECTANGLE:
                    {
                        return ascRectangleComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case CIRCLE:
                    {
                        return ascCircleComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case POINT:
                    {
                        return ascPointComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case POINT3D:
                    {
                        return ascPoint3DComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case LINE:
                    {
                        return ascLineComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case POLYGON:
                    {
                        return ascPolygonComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case DURATION:
                    {
                        return ascDurationComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case INTERVAL:
                    {
                        return ascIntervalComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                case BINARY:
                    {
                        return ascByteArrayComp.compare(b1, s1 + 1, l1 - 1, b2, s2 + 1, l2 - 1);
                    }
                default:
                    {
                        // We include typeTag in comparison to compare between two type to enforce some ordering
                        return rawComp.compare(b1, s1, l1, b2, s2, l2);
                    }
            }
        }
    };
}
Also used : ITypeConvertComputer(org.apache.asterix.om.types.hierachy.ITypeConvertComputer) PointableBinaryComparatorFactory(org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory) ArrayBackedValueStorage(org.apache.hyracks.data.std.util.ArrayBackedValueStorage) ATypeTag(org.apache.asterix.om.types.ATypeTag) IBinaryComparator(org.apache.hyracks.api.dataflow.value.IBinaryComparator) IOException(java.io.IOException) HyracksDataException(org.apache.hyracks.api.exceptions.HyracksDataException)

Example 2 with PointableBinaryComparatorFactory

use of org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory in project asterixdb by apache.

the class ListItemBinaryComparatorFactory method createBinaryComparator.

public IBinaryComparator createBinaryComparator(final ATypeTag firstItemTypeTag, final ATypeTag secondItemTypeTag, final boolean ignoreCase) {
    return new IBinaryComparator() {

        final IBinaryComparator ascBoolComp = BooleanBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY).createBinaryComparator();

        final IBinaryComparator ascLongComp = LongBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY).createBinaryComparator();

        final IBinaryComparator ascLowerCaseStrComp = new PointableBinaryComparatorFactory(UTF8StringLowercasePointable.FACTORY).createBinaryComparator();

        final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY).createBinaryComparator();

        final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY).createBinaryComparator();

        final IBinaryComparator ascRectangleComp = ARectanglePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascCircleComp = ACirclePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascDurationComp = ADurationPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascIntervalComp = AIntervalAscPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascLineComp = ALinePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascPointComp = APointPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascPoint3DComp = APoint3DPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascPolygonComp = APolygonPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascUUIDComp = AUUIDPartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        final IBinaryComparator ascByteArrayComp = new PointableBinaryComparatorFactory(ByteArrayPointable.FACTORY).createBinaryComparator();

        final IBinaryComparator rawComp = RawBinaryComparatorFactory.INSTANCE.createBinaryComparator();

        @Override
        public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) throws HyracksDataException {
            //  A list item cannot be MISSING.
            if (b1[s1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                    return 0;
                } else {
                    return -1;
                }
            } else {
                if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                    return 1;
                }
            }
            ATypeTag tag1 = firstItemTypeTag;
            int skip1 = 0;
            if (firstItemTypeTag == ATypeTag.ANY) {
                tag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b1[s1]);
                skip1 = 1;
            }
            ATypeTag tag2 = secondItemTypeTag;
            int skip2 = 0;
            if (secondItemTypeTag == ATypeTag.ANY) {
                tag2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b2[s2]);
                skip2 = 1;
            }
            if (tag1 != tag2) {
                return rawComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
            }
            switch(tag1) {
                case UUID:
                    {
                        return ascUUIDComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case BOOLEAN:
                    {
                        return ascBoolComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case TIME:
                case DATE:
                case YEARMONTHDURATION:
                case INTEGER:
                    {
                        return ascIntComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case DATETIME:
                case DAYTIMEDURATION:
                case BIGINT:
                    {
                        return ascLongComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case FLOAT:
                    {
                        return ascFloatComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case DOUBLE:
                    {
                        return ascDoubleComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case STRING:
                    {
                        if (ignoreCase) {
                            return ascLowerCaseStrComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                        } else {
                            return ascStrComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                        }
                    }
                case RECTANGLE:
                    {
                        return ascRectangleComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case CIRCLE:
                    {
                        return ascCircleComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case POINT:
                    {
                        return ascPointComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case POINT3D:
                    {
                        return ascPoint3DComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case LINE:
                    {
                        return ascLineComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case POLYGON:
                    {
                        return ascPolygonComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case DURATION:
                    {
                        return ascDurationComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case INTERVAL:
                    {
                        return ascIntervalComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                case BINARY:
                    {
                        return ascByteArrayComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
                default:
                    {
                        return rawComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
                    }
            }
        }
    };
}
Also used : PointableBinaryComparatorFactory(org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory) ATypeTag(org.apache.asterix.om.types.ATypeTag) IBinaryComparator(org.apache.hyracks.api.dataflow.value.IBinaryComparator)

Aggregations

ATypeTag (org.apache.asterix.om.types.ATypeTag)2 IBinaryComparator (org.apache.hyracks.api.dataflow.value.IBinaryComparator)2 PointableBinaryComparatorFactory (org.apache.hyracks.data.std.accessors.PointableBinaryComparatorFactory)2 IOException (java.io.IOException)1 ITypeConvertComputer (org.apache.asterix.om.types.hierachy.ITypeConvertComputer)1 HyracksDataException (org.apache.hyracks.api.exceptions.HyracksDataException)1 ArrayBackedValueStorage (org.apache.hyracks.data.std.util.ArrayBackedValueStorage)1