public IScalarEvaluator createScalarEvaluator()

in asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/CreateMBREvalFactory.java [67:377]


    public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
        return new IScalarEvaluator() {
            private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
            private final DataOutput out = resultStorage.getDataOutput();
            private final IPointable inputArg0 = new VoidPointable();
            private final IPointable inputArg1 = new VoidPointable();
            private final IPointable inputArg2 = new VoidPointable();

            private IScalarEvaluator eval0 = recordEvalFactory.createScalarEvaluator(ctx);
            private IScalarEvaluator eval1 = dimensionEvalFactory.createScalarEvaluator(ctx);
            private IScalarEvaluator eval2 = coordinateEvalFactory.createScalarEvaluator(ctx);

            @Override
            public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
                eval0.evaluate(tuple, inputArg0);
                eval1.evaluate(tuple, inputArg1);
                eval2.evaluate(tuple, inputArg2);

                if (PointableHelper.checkAndSetMissingOrNull(result, inputArg0, inputArg1, inputArg2)) {
                    return;
                }

                byte[] data0 = inputArg0.getByteArray();
                byte[] data1 = inputArg1.getByteArray();
                byte[] data2 = inputArg2.getByteArray();
                int startOffset0 = inputArg0.getStartOffset();
                int startOffset1 = inputArg1.getStartOffset();
                int startOffset2 = inputArg2.getStartOffset();

                try {
                    resultStorage.reset();
                    if (data0[startOffset0] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG
                            || data1[startOffset1] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG
                            || data2[startOffset2] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
                        out.writeByte(ATypeTag.SERIALIZED_MISSING_TYPE_TAG);
                        result.set(resultStorage);
                        return;
                    }
                    if (data0[startOffset0] == ATypeTag.SERIALIZED_NULL_TYPE_TAG
                            || data1[startOffset1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG
                            || data2[startOffset2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                        out.writeByte(ATypeTag.SERIALIZED_NULL_TYPE_TAG);
                        result.set(resultStorage);
                        return;
                    }
                    if (data1[startOffset1] != ATypeTag.SERIALIZED_INT32_TYPE_TAG) {
                        throw new TypeMismatchException(BuiltinFunctions.CREATE_MBR, 1, data1[startOffset1],
                                ATypeTag.SERIALIZED_INT32_TYPE_TAG);
                    }
                    int dimension = AInt32SerializerDeserializer.getInt(data1, startOffset1 + 1);

                    if (data2[startOffset2] != ATypeTag.SERIALIZED_INT32_TYPE_TAG) {
                        throw new TypeMismatchException(BuiltinFunctions.CREATE_MBR, 2, data2[startOffset2],
                                ATypeTag.SERIALIZED_INT32_TYPE_TAG);
                    }
                    int coordinate = AInt32SerializerDeserializer.getInt(data2, startOffset2 + 1);
                    double value;
                    if (dimension == 2) {
                        ATypeTag tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(data0[startOffset0]);
                        switch (tag) {
                            case POINT:
                                switch (coordinate) {
                                    case 0: // 0 is for min x, 1 is for min y, 2
                                                // for
                                            // max x, and 3 for max y
                                    case 2: {
                                        double x = ADoubleSerializerDeserializer.getDouble(data0, startOffset0 + 1
                                                + APointSerializerDeserializer.getCoordinateOffset(Coordinate.X));
                                        value = x;
                                    }
                                        break;
                                    case 1:
                                    case 3: {
                                        double y = ADoubleSerializerDeserializer.getDouble(data0, startOffset0 + 1
                                                + APointSerializerDeserializer.getCoordinateOffset(Coordinate.Y));

                                        value = y;
                                    }
                                        break;
                                    default: {
                                        throw new NotImplementedException(
                                                coordinate + " is not a valid coordinate option");
                                    }
                                }
                                break;
                            case LINE:
                                value = Double.MAX_VALUE;
                                switch (coordinate) {
                                    case 0: {
                                        value = Double.MAX_VALUE;
                                        double startX = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getStartPointCoordinateOffset(Coordinate.X));
                                        double endX = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getEndPointCoordinateOffset(Coordinate.X));

                                        value = Math.min(Math.min(startX, endX), value);
                                    }
                                        break;
                                    case 1: {
                                        value = Double.MAX_VALUE;
                                        double startY = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getStartPointCoordinateOffset(Coordinate.Y));
                                        double endY = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getEndPointCoordinateOffset(Coordinate.Y));

                                        value = Math.min(Math.min(startY, endY), value);
                                    }
                                        break;
                                    case 2: {
                                        value = Double.MIN_VALUE;
                                        double startX = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getStartPointCoordinateOffset(Coordinate.X));
                                        double endX = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getEndPointCoordinateOffset(Coordinate.X));

                                        value = Math.max(Math.min(startX, endX), value);
                                    }
                                        break;
                                    case 3: {
                                        value = Double.MIN_VALUE;
                                        double startY = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getStartPointCoordinateOffset(Coordinate.Y));
                                        double endY = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ALineSerializerDeserializer
                                                        .getEndPointCoordinateOffset(Coordinate.Y));

                                        value = Math.max(Math.min(startY, endY), value);
                                    }
                                        break;
                                    default: {
                                        throw new NotImplementedException(
                                                coordinate + " is not a valid coordinate option");
                                    }
                                }
                                break;
                            case POLYGON:
                                int numOfPoints = AInt16SerializerDeserializer.getShort(data0,
                                        startOffset0 + 1 + APolygonSerializerDeserializer.getNumberOfPointsOffset());
                                switch (coordinate) {
                                    case 0: {
                                        value = Double.MAX_VALUE;
                                        for (int i = 0; i < numOfPoints; i++) {
                                            double x = ADoubleSerializerDeserializer.getDouble(data0,
                                                    startOffset0 + 1 + APolygonSerializerDeserializer
                                                            .getCoordinateOffset(i, Coordinate.X));
                                            value = Math.min(x, value);
                                        }
                                    }
                                        break;
                                    case 1: {
                                        value = Double.MAX_VALUE;
                                        for (int i = 0; i < numOfPoints; i++) {
                                            double y = ADoubleSerializerDeserializer.getDouble(data0,
                                                    startOffset0 + 1 + APolygonSerializerDeserializer
                                                            .getCoordinateOffset(i, Coordinate.Y));
                                            value = Math.min(y, value);
                                        }
                                    }
                                        break;
                                    case 2: {
                                        value = Double.MIN_VALUE;
                                        for (int i = 0; i < numOfPoints; i++) {
                                            double x = ADoubleSerializerDeserializer.getDouble(data0,
                                                    startOffset0 + 1 + APolygonSerializerDeserializer
                                                            .getCoordinateOffset(i, Coordinate.X));
                                            value = Math.max(x, value);
                                        }
                                    }
                                        break;
                                    case 3: {
                                        value = Double.MIN_VALUE;
                                        for (int i = 0; i < numOfPoints; i++) {
                                            double y = ADoubleSerializerDeserializer.getDouble(data0,
                                                    startOffset0 + 1 + APolygonSerializerDeserializer
                                                            .getCoordinateOffset(i, Coordinate.Y));
                                            value = Math.max(y, value);
                                        }
                                    }
                                        break;
                                    default: {
                                        throw new NotImplementedException(
                                                coordinate + " is not a valid coordinate option");
                                    }
                                }
                                break;
                            case GEOMETRY:
                                Geometry geometry = AGeometrySerializerDeserializer
                                        .getAGeometryObject(data0, startOffset0 + 1).getGeometry();
                                Envelope envelope = geometry.getEnvelopeInternal();
                                switch (coordinate) {
                                    case 0:
                                        value = envelope.getMinX();
                                        break;
                                    case 1:
                                        value = envelope.getMinY();
                                        break;
                                    case 2:
                                        value = envelope.getMaxX();
                                        break;
                                    case 3:
                                        value = envelope.getMaxY();
                                        break;
                                    default:
                                        throw new IllegalArgumentException(
                                                coordinate + " is not a valid coordinate option");
                                }
                                break;
                            case CIRCLE:
                                switch (coordinate) {
                                    case 0: {
                                        double x = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer
                                                        .getCenterPointCoordinateOffset(Coordinate.X));
                                        double radius = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer.getRadiusOffset());
                                        value = x - radius;
                                    }
                                        break;
                                    case 1: {
                                        double y = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer
                                                        .getCenterPointCoordinateOffset(Coordinate.Y));
                                        double radius = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer.getRadiusOffset());

                                        value = y - radius;
                                    }
                                        break;
                                    case 2: {
                                        double x = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer
                                                        .getCenterPointCoordinateOffset(Coordinate.X));
                                        double radius = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer.getRadiusOffset());

                                        value = x + radius;
                                    }
                                        break;
                                    case 3: {
                                        double y = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer
                                                        .getCenterPointCoordinateOffset(Coordinate.Y));
                                        double radius = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ACircleSerializerDeserializer.getRadiusOffset());

                                        value = y + radius;
                                    }
                                        break;
                                    default: {
                                        throw new NotImplementedException(
                                                coordinate + " is not a valid coordinate option");
                                    }
                                }
                                break;
                            case RECTANGLE:
                                switch (coordinate) {
                                    case 0: {
                                        value = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ARectangleSerializerDeserializer
                                                        .getBottomLeftCoordinateOffset(Coordinate.X));
                                    }
                                        break;
                                    case 1: {
                                        value = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ARectangleSerializerDeserializer
                                                        .getBottomLeftCoordinateOffset(Coordinate.Y));
                                    }
                                        break;
                                    case 2: {
                                        value = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ARectangleSerializerDeserializer
                                                        .getUpperRightCoordinateOffset(Coordinate.X));
                                    }
                                        break;
                                    case 3: {
                                        value = ADoubleSerializerDeserializer.getDouble(data0,
                                                startOffset0 + 1 + ARectangleSerializerDeserializer
                                                        .getUpperRightCoordinateOffset(Coordinate.Y));
                                    }
                                        break;
                                    default: {
                                        throw new NotImplementedException(
                                                coordinate + " is not a valid coordinate option");
                                    }
                                }
                                break;
                            default:
                                throw new TypeMismatchException(BuiltinFunctions.CREATE_MBR, 0, data0[startOffset0],
                                        ATypeTag.SERIALIZED_POINT_TYPE_TAG, ATypeTag.SERIALIZED_LINE_TYPE_TAG,
                                        ATypeTag.SERIALIZED_POLYGON_TYPE_TAG, ATypeTag.SERIALIZED_CIRCLE_TYPE_TAG,
                                        ATypeTag.SERIALIZED_RECTANGLE_TYPE_TAG, ATypeTag.SERIALIZED_GEOMETRY_TYPE_TAG);
                        }
                    } else {
                        throw new NotImplementedException(dimension + "D is not supported");
                    }
                    out.writeByte(ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG);
                    out.writeDouble(value);
                } catch (IOException e) {
                    throw HyracksDataException.create(e);
                }
                result.set(resultStorage);
            }
        };
    }