in src/org/apache/pig/data/BinInterSedes.java [792:1050]
private int compareBinInterSedesDatum(ByteBuffer bb1, ByteBuffer bb2, boolean[] asc) throws IOException {
int rc = 0;
byte type1, type2;
byte dt1 = bb1.get();
byte dt2 = bb2.get();
switch (dt1) {
case BinInterSedes.NULL: {
type1 = DataType.NULL;
type2 = getGeneralizedDataType(dt2);
if (asc != null) // we are scanning the top-level Tuple (original call)
mHasNullField = true;
if (type1 == type2)
rc = 0;
break;
}
case BinInterSedes.BOOLEAN_TRUE:
case BinInterSedes.BOOLEAN_FALSE: {
type1 = DataType.BOOLEAN;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
// false < true
int bv1 = (dt1 == BinInterSedes.BOOLEAN_TRUE) ? 1 : 0;
int bv2 = (dt2 == BinInterSedes.BOOLEAN_TRUE) ? 1 : 0;
rc = bv1 - bv2;
}
break;
}
case BinInterSedes.BYTE: {
type1 = DataType.BYTE;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
byte bv1 = bb1.get();
byte bv2 = bb2.get();
rc = (bv1 < bv2 ? -1 : (bv1 == bv2 ? 0 : 1));
}
break;
}
case BinInterSedes.INTEGER_0:
case BinInterSedes.INTEGER_1:
case BinInterSedes.INTEGER_INBYTE:
case BinInterSedes.INTEGER_INSHORT:
case BinInterSedes.INTEGER: {
type1 = DataType.INTEGER;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
int iv1 = readInt(bb1, dt1);
int iv2 = readInt(bb2, dt2);
rc = (iv1 < iv2 ? -1 : (iv1 == iv2 ? 0 : 1));
}
break;
}
case BinInterSedes.LONG_0:
case BinInterSedes.LONG_1:
case BinInterSedes.LONG_INBYTE:
case BinInterSedes.LONG_INSHORT:
case BinInterSedes.LONG_ININT:
case BinInterSedes.LONG: {
type1 = DataType.LONG;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
long lv1 = readLong(bb1, dt1);
long lv2 = readLong(bb2, dt2);
rc = (lv1 < lv2 ? -1 : (lv1 == lv2 ? 0 : 1));
}
break;
}
case BinInterSedes.DATETIME: {
type1 = DataType.DATETIME;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
long lv1 = bb1.getLong();
bb1.position(bb1.position() + 2); // move cursor forward without read the timezone bytes
long lv2 = bb2.getLong();
bb2.position(bb2.position() + 2);
rc = (lv1 < lv2 ? -1 : (lv1 == lv2 ? 0 : 1));
}
break;
}
case BinInterSedes.FLOAT: {
type1 = DataType.FLOAT;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
float fv1 = bb1.getFloat();
float fv2 = bb2.getFloat();
rc = Float.compare(fv1, fv2);
}
break;
}
case BinInterSedes.DOUBLE: {
type1 = DataType.DOUBLE;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
double dv1 = bb1.getDouble();
double dv2 = bb2.getDouble();
rc = Double.compare(dv1, dv2);
}
break;
}
case BinInterSedes.BIGINTEGER: {
type1 = DataType.BIGINTEGER;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
int sz1 = readSize(bb1, bb1.get());
int sz2 = readSize(bb2, bb2.get());
byte[] ca1 = new byte[sz1];
byte[] ca2 = new byte[sz2];
bb1.get(ca1);
bb2.get(ca2);
String str1 = null, str2 = null;
try {
str1 = new String(ca1, BinInterSedes.UTF8);
str2 = new String(ca2, BinInterSedes.UTF8);
} catch (UnsupportedEncodingException uee) {
mLog.warn("Unsupported string encoding", uee);
uee.printStackTrace();
}
if (str1 != null && str2 != null) {
rc = new BigInteger(str1).compareTo(new BigInteger(str2));
}
}
break;
}
case BinInterSedes.BIGDECIMAL: {
type1 = DataType.BIGDECIMAL;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
int sz1 = readSize(bb1, bb1.get());
int sz2 = readSize(bb2, bb2.get());
byte[] ca1 = new byte[sz1];
byte[] ca2 = new byte[sz2];
bb1.get(ca1);
bb2.get(ca2);
String str1 = null, str2 = null;
try {
str1 = new String(ca1, BinInterSedes.UTF8);
str2 = new String(ca2, BinInterSedes.UTF8);
} catch (UnsupportedEncodingException uee) {
mLog.warn("Unsupported string encoding", uee);
uee.printStackTrace();
}
if (str1 != null && str2 != null) {
rc = new BigDecimal(str1).compareTo(new BigDecimal(str2));
}
}
break;
}
case BinInterSedes.TINYBYTEARRAY:
case BinInterSedes.SMALLBYTEARRAY:
case BinInterSedes.BYTEARRAY: {
type1 = DataType.BYTEARRAY;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
int basz1 = readSize(bb1, dt1);
int basz2 = readSize(bb2, dt2);
rc = WritableComparator.compareBytes(
bb1.array(), bb1.position(), basz1,
bb2.array(), bb2.position(), basz2);
bb1.position(bb1.position() + basz1);
bb2.position(bb2.position() + basz2);
}
break;
}
case BinInterSedes.SMALLCHARARRAY:
case BinInterSedes.CHARARRAY: {
type1 = DataType.CHARARRAY;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
int casz1 = readSize(bb1, dt1);
int casz2 = readSize(bb2, dt2);
String str1 = null, str2 = null;
try {
str1 = new String(bb1.array(), bb1.position(), casz1, BinInterSedes.UTF8);
str2 = new String(bb2.array(), bb2.position(), casz2, BinInterSedes.UTF8);
} catch (UnsupportedEncodingException uee) {
mLog.warn("Unsupported string encoding", uee);
uee.printStackTrace();
} finally {
bb1.position(bb1.position() + casz1);
bb2.position(bb2.position() + casz2);
}
if (str1 != null && str2 != null)
rc = str1.compareTo(str2);
}
break;
}
case BinInterSedes.TUPLE_0:
case BinInterSedes.TUPLE_1:
case BinInterSedes.TUPLE_2:
case BinInterSedes.TUPLE_3:
case BinInterSedes.TUPLE_4:
case BinInterSedes.TUPLE_5:
case BinInterSedes.TUPLE_6:
case BinInterSedes.TUPLE_7:
case BinInterSedes.TUPLE_8:
case BinInterSedes.TUPLE_9:
case BinInterSedes.TINYTUPLE:
case BinInterSedes.SMALLTUPLE:
case BinInterSedes.TUPLE: {
type1 = DataType.TUPLE;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2) {
// first compare sizes
int tsz1 = readSize(bb1, dt1);
int tsz2 = readSize(bb2, dt2);
if (tsz1 > tsz2)
return 1;
else if (tsz1 < tsz2)
return -1;
else {
// if sizes are the same, compare field by field. If we are doing secondary sort, use the sort
// order passed by the caller. Inner tuples never have sort order (so we pass null).
for (int i = 0; i < tsz1 && rc == 0; i++) {
rc = compareBinInterSedesDatum(bb1, bb2, null);
if (rc != 0 && asc != null && asc.length > 1 && !asc[i])
rc *= -1;
}
}
}
break;
}
case BinInterSedes.TINYBAG:
case BinInterSedes.SMALLBAG:
case BinInterSedes.BAG: {
type1 = DataType.BAG;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2)
rc = compareBinInterSedesBag(bb1, bb2, dt1, dt2);
break;
}
case BinInterSedes.TINYMAP:
case BinInterSedes.SMALLMAP:
case BinInterSedes.MAP: {
type1 = DataType.MAP;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2)
rc = compareBinInterSedesMap(bb1, bb2, dt1, dt2);
break;
}
case BinInterSedes.GENERIC_WRITABLECOMPARABLE: {
type1 = DataType.GENERIC_WRITABLECOMPARABLE;
type2 = getGeneralizedDataType(dt2);
if (type1 == type2)
rc = compareBinInterSedesGenericWritableComparable(bb1, bb2);
break;
}
default: {
mLog.info("Unsupported DataType for binary comparison, switching to object deserialization: "
+ DataType.genTypeToNameMap().get(dt1) + "(" + dt1 + ")");
throw new UnsupportedEncodingException();
}
}
// compare generalized data types
if (type1 != type2)
rc = (type1 < type2) ? -1 : 1;
// apply sort order for keys that are not tuples or for whole tuples
if (asc != null && asc.length == 1 && !asc[0])
rc *= -1;
return rc;
}