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);
}
};
}