int v = ioi.get(o);
serializeInt(buffer, v, invert);
return;
}
case LONG: {
LongObjectInspector loi = (LongObjectInspector) poi;
long v = loi.get(o);
writeByte(buffer, (byte) ((v >> 56) ^ 0x80), invert);
writeByte(buffer, (byte) (v >> 48), invert);
writeByte(buffer, (byte) (v >> 40), invert);
writeByte(buffer, (byte) (v >> 32), invert);
writeByte(buffer, (byte) (v >> 24), invert);
writeByte(buffer, (byte) (v >> 16), invert);
writeByte(buffer, (byte) (v >> 8), invert);
writeByte(buffer, (byte) v, invert);
return;
}
case FLOAT: {
FloatObjectInspector foi = (FloatObjectInspector) poi;
int v = Float.floatToIntBits(foi.get(o));
if ((v & (1 << 31)) != 0) {
// negative number, flip all bits
v = ~v;
} else {
// positive number, flip the first bit
v = v ^ (1 << 31);
}
writeByte(buffer, (byte) (v >> 24), invert);
writeByte(buffer, (byte) (v >> 16), invert);
writeByte(buffer, (byte) (v >> 8), invert);
writeByte(buffer, (byte) v, invert);
return;
}
case DOUBLE: {
DoubleObjectInspector doi = (DoubleObjectInspector) poi;
long v = Double.doubleToLongBits(doi.get(o));
if ((v & (1L << 63)) != 0) {
// negative number, flip all bits
v = ~v;
} else {
// positive number, flip the first bit
v = v ^ (1L << 63);
}
writeByte(buffer, (byte) (v >> 56), invert);
writeByte(buffer, (byte) (v >> 48), invert);
writeByte(buffer, (byte) (v >> 40), invert);
writeByte(buffer, (byte) (v >> 32), invert);
writeByte(buffer, (byte) (v >> 24), invert);
writeByte(buffer, (byte) (v >> 16), invert);
writeByte(buffer, (byte) (v >> 8), invert);
writeByte(buffer, (byte) v, invert);
return;
}
case STRING: {
StringObjectInspector soi = (StringObjectInspector) poi;
Text t = soi.getPrimitiveWritableObject(o);
serializeBytes(buffer, t.getBytes(), t.getLength(), invert);
return;
}
case CHAR: {
HiveCharObjectInspector hcoi = (HiveCharObjectInspector) poi;
HiveCharWritable hc = hcoi.getPrimitiveWritableObject(o);
// Trailing space should ignored for char comparisons.
// So write stripped values for this SerDe.
Text t = hc.getStrippedValue();
serializeBytes(buffer, t.getBytes(), t.getLength(), invert);
return;
}
case VARCHAR: {
HiveVarcharObjectInspector hcoi = (HiveVarcharObjectInspector)poi;
HiveVarcharWritable hc = hcoi.getPrimitiveWritableObject(o);
// use varchar's text field directly
Text t = hc.getTextValue();
serializeBytes(buffer, t.getBytes(), t.getLength(), invert);
return;
}
case BINARY: {
BinaryObjectInspector baoi = (BinaryObjectInspector) poi;
BytesWritable ba = baoi.getPrimitiveWritableObject(o);
byte[] toSer = new byte[ba.getLength()];
System.arraycopy(ba.getBytes(), 0, toSer, 0, ba.getLength());
serializeBytes(buffer, toSer, ba.getLength(), invert);
return;
}
case DATE: {
DateObjectInspector doi = (DateObjectInspector) poi;
int v = doi.getPrimitiveWritableObject(o).getDays();
serializeInt(buffer, v, invert);
return;
}
case TIMESTAMP: {
TimestampObjectInspector toi = (TimestampObjectInspector) poi;
TimestampWritable t = toi.getPrimitiveWritableObject(o);
byte[] data = t.getBinarySortable();
for (int i = 0; i < data.length; i++) {
writeByte(buffer, data[i], invert);
}
return;
}
case DECIMAL: {
// decimals are encoded in three pieces:
// sign: 1, 2 or 3 for smaller, equal or larger than 0 respectively
// factor: Number that indicates the amount of digits you have to move
// the decimal point left or right until the resulting number is smaller
// than zero but has something other than 0 as the first digit.
// digits: which is a string of all the digits in the decimal. If the number
// is negative the binary string will be inverted to get the correct ordering.
// Example: 0.00123
// Sign is 3 (bigger than 0)
// Factor is -2 (move decimal point 2 positions right)
// Digits are: 123
HiveDecimalObjectInspector boi = (HiveDecimalObjectInspector) poi;
HiveDecimal dec = boi.getPrimitiveJavaObject(o);
// get the sign of the big decimal
int sign = dec.compareTo(HiveDecimal.ZERO);
// we'll encode the absolute value (sign is separate)
dec = dec.abs();
// get the scale factor to turn big decimal into a decimal < 1
int factor = dec.precision() - dec.scale();
factor = sign == 1 ? factor : -factor;
// convert the absolute big decimal to string
dec.scaleByPowerOfTen(Math.abs(dec.scale()));
String digits = dec.unscaledValue().toString();
// finally write out the pieces (sign, scale, digits)
writeByte(buffer, (byte) ( sign + 1), invert);
writeByte(buffer, (byte) ((factor >> 24) ^ 0x80), invert);
writeByte(buffer, (byte) ( factor >> 16), invert);
writeByte(buffer, (byte) ( factor >> 8), invert);
writeByte(buffer, (byte) factor, invert);
serializeBytes(buffer, digits.getBytes(decimalCharSet),
digits.length(), sign == -1 ? !invert : invert);
return;
}
default: {
throw new RuntimeException("Unrecognized type: "
+ poi.getPrimitiveCategory());
}
}
}
case LIST: {
ListObjectInspector loi = (ListObjectInspector) oi;
ObjectInspector eoi = loi.getListElementObjectInspector();
// \1 followed by each element
int size = loi.getListLength(o);
for (int eid = 0; eid < size; eid++) {
writeByte(buffer, (byte) 1, invert);
serialize(buffer, loi.getListElement(o, eid), eoi, invert);
}
// and \0 to terminate
writeByte(buffer, (byte) 0, invert);
return;
}