public TimestampWritable evaluate(TimestampWritable t) {
   if (t == null) {
     return null;
   }
   long newTimestamp = granularity.truncate(t.getTimestamp().getTime());
   result.setTime(newTimestamp);
   return result;
 }
  private void compareToUDFUnixTimeStampDate(long t, long y) {
    TimestampWritable tsw = toTimestampWritable(t);
    LongWritable res = getLongWritable(tsw);
    if (res.get() != y) {
      System.out.printf(
          "%d vs %d for %d, %d\n", res.get(), y, t, tsw.getTimestamp().getTime() / 1000);
    }

    Assert.assertEquals(res.get(), y);
  }
 public int compareTo(TimestampWritable t) {
   checkBytes();
   long s1 = this.getSeconds();
   long s2 = t.getSeconds();
   if (s1 == s2) {
     int n1 = this.getNanos();
     int n2 = t.getNanos();
     if (n1 == n2) {
       return 0;
     }
     return n1 - n2;
   } else {
     return s1 < s2 ? -1 : 1;
   }
 }
  public void readFields(DataInput in) throws IOException {
    in.readFully(internalBytes, 0, 4);
    if (TimestampWritable.hasDecimalOrSecondVInt(internalBytes[0])) {
      in.readFully(internalBytes, 4, 1);
      int len = (byte) WritableUtils.decodeVIntSize(internalBytes[4]);
      if (len > 1) {
        in.readFully(internalBytes, 5, len - 1);
      }

      long vlong = LazyBinaryUtils.readVLongFromByteArray(internalBytes, 4);
      if (vlong < -1000000000 || vlong > 999999999) {
        throw new IOException(
            "Invalid first vint value (encoded nanoseconds) of a TimestampWritable: "
                + vlong
                + ", expected to be between -1000000000 and 999999999.");
        // Note that -1000000000 is a valid value corresponding to a nanosecond timestamp
        // of 999999999, because if the second VInt is present, we use the value
        // (-reversedNanoseconds - 1) as the second VInt.
      }
      if (vlong < 0) {
        // This indicates there is a second VInt containing the additional bits of the seconds
        // field.
        in.readFully(internalBytes, 4 + len, 1);
        int secondVIntLen = (byte) WritableUtils.decodeVIntSize(internalBytes[4 + len]);
        if (secondVIntLen > 1) {
          in.readFully(internalBytes, 5 + len, secondVIntLen - 1);
        }
      }
    }
    currentBytes = internalBytes;
    this.offset = 0;
  }
 /**
  * Convert from Timestamp to an integer. This is called for CAST(... AS INT)
  *
  * @param i The Timestamp value to convert
  * @return IntWritable
  */
 public IntWritable evaluate(TimestampWritable i) {
   if (i == null) {
     return null;
   } else {
     intWritable.set(i.getSeconds());
     return intWritable;
   }
 }
 public static void setTimestamp(Timestamp t, byte[] bytes, int offset) {
   boolean hasDecimalOrSecondVInt = hasDecimalOrSecondVInt(bytes[offset]);
   long seconds = (long) TimestampWritable.getSeconds(bytes, offset);
   int nanos = 0;
   if (hasDecimalOrSecondVInt) {
     nanos = TimestampWritable.getNanos(bytes, offset + 4);
     if (hasSecondVInt(bytes[offset + 4])) {
       seconds +=
           LazyBinaryUtils.readVLongFromByteArray(
               bytes, offset + 4 + WritableUtils.decodeVIntSize(bytes[offset + 4]));
     }
   }
   t.setTime(seconds * 1000);
   if (nanos != 0) {
     t.setNanos(nanos);
   }
 }
Exemple #7
0
  public IntWritable evaluate(TimestampWritable t) {
    if (t == null) {
      return null;
    }

    calendar.setTime(t.getTimestamp());
    result.set(1 + calendar.get(Calendar.MONTH));
    return result;
  }
 private LongWritable getLongWritable(TimestampWritable i) {
   LongWritable result = new LongWritable();
   if (i == null) {
     return null;
   } else {
     result.set(i.getSeconds());
     return result;
   }
 }
 /** @return nanoseconds in this TimestampWritable */
 public int getNanos() {
   if (!timestampEmpty) {
     return timestamp.getNanos();
   } else if (!bytesEmpty) {
     return hasDecimalOrSecondVInt() ? TimestampWritable.getNanos(currentBytes, offset + 4) : 0;
   } else {
     throw new IllegalStateException("Both timestamp and bytes are empty");
   }
 }
 /** @return seconds corresponding to this TimestampWritable */
 public long getSeconds() {
   if (!timestampEmpty) {
     return millisToSeconds(timestamp.getTime());
   } else if (!bytesEmpty) {
     return TimestampWritable.getSeconds(currentBytes, offset);
   } else {
     throw new IllegalStateException("Both timestamp and bytes are empty");
   }
 }
  @Test
  public void testTimestampPlusIntervalDayTime() throws Exception {
    GenericUDFOPPlus udf = new GenericUDFOPPlus();

    TimestampWritable left = new TimestampWritable(Timestamp.valueOf("2001-01-01 00:00:00"));
    HiveIntervalDayTimeWritable right =
        new HiveIntervalDayTimeWritable(HiveIntervalDayTime.valueOf("1 2:3:4.567"));
    ObjectInspector[] inputOIs = {
      PrimitiveObjectInspectorFactory.writableTimestampObjectInspector,
      PrimitiveObjectInspectorFactory.writableHiveIntervalDayTimeObjectInspector
    };
    DeferredObject[] args = {
      new DeferredJavaObject(left), new DeferredJavaObject(right),
    };

    PrimitiveObjectInspector oi = (PrimitiveObjectInspector) udf.initialize(inputOIs);
    Assert.assertEquals(TypeInfoFactory.timestampTypeInfo, oi.getTypeInfo());
    TimestampWritable res = (TimestampWritable) udf.evaluate(args);
    Assert.assertEquals(Timestamp.valueOf("2001-01-02 2:3:4.567"), res.getTimestamp());
  }
 public void set(TimestampWritable t) {
   if (t.bytesEmpty) {
     set(t.getTimestamp());
     return;
   }
   if (t.currentBytes == t.externalBytes) {
     set(t.currentBytes, t.offset);
   } else {
     set(t.currentBytes, 0);
   }
 }
  @Test
  public void testTimestampPlusIntervalYearMonth() throws Exception {
    GenericUDFOPPlus udf = new GenericUDFOPPlus();

    TimestampWritable left =
        new TimestampWritable(Timestamp.valueOf("2001-11-15 01:02:03.123456789"));
    HiveIntervalYearMonthWritable right =
        new HiveIntervalYearMonthWritable(HiveIntervalYearMonth.valueOf("2-2"));
    ObjectInspector[] inputOIs = {
      PrimitiveObjectInspectorFactory.writableTimestampObjectInspector,
      PrimitiveObjectInspectorFactory.writableHiveIntervalYearMonthObjectInspector
    };
    DeferredObject[] args = {
      new DeferredJavaObject(left), new DeferredJavaObject(right),
    };

    PrimitiveObjectInspector oi = (PrimitiveObjectInspector) udf.initialize(inputOIs);
    Assert.assertEquals(TypeInfoFactory.timestampTypeInfo, oi.getTypeInfo());
    TimestampWritable res = (TimestampWritable) udf.evaluate(args);
    Assert.assertEquals(Timestamp.valueOf("2004-01-15 01:02:03.123456789"), res.getTimestamp());
  }
 /**
  * Check a particular field and set its size and offset in bytes based on the field type and the
  * bytes arrays.
  *
  * <p>For void, boolean, byte, short, int, long, float and double, there is no offset and the size
  * is fixed. For string, map, list, struct, the first four bytes are used to store the size. So
  * the offset is 4 and the size is computed by concating the first four bytes together. The first
  * four bytes are defined with respect to the offset in the bytes arrays. For timestamp, if the
  * first bit is 0, the record length is 4, otherwise a VInt begins at the 5th byte and its length
  * is added to 4.
  *
  * @param objectInspector object inspector of the field
  * @param bytes bytes arrays store the table row
  * @param offset offset of this field
  * @param recordInfo modify this byteinfo object and return it
  */
 public static void checkObjectByteInfo(
     ObjectInspector objectInspector, byte[] bytes, int offset, RecordInfo recordInfo, VInt vInt) {
   Category category = objectInspector.getCategory();
   switch (category) {
     case PRIMITIVE:
       PrimitiveCategory primitiveCategory =
           ((PrimitiveObjectInspector) objectInspector).getPrimitiveCategory();
       switch (primitiveCategory) {
         case VOID:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = 0;
           break;
         case BOOLEAN:
         case BYTE:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = 1;
           break;
         case SHORT:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = 2;
           break;
         case FLOAT:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = 4;
           break;
         case DOUBLE:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = 8;
           break;
         case INT:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = WritableUtils.decodeVIntSize(bytes[offset]);
           break;
         case LONG:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = WritableUtils.decodeVIntSize(bytes[offset]);
           break;
         case STRING:
           // using vint instead of 4 bytes
           LazyBinaryUtils.readVInt(bytes, offset, vInt);
           recordInfo.elementOffset = vInt.length;
           recordInfo.elementSize = vInt.value;
           break;
         case CHAR:
         case VARCHAR:
           LazyBinaryUtils.readVInt(bytes, offset, vInt);
           recordInfo.elementOffset = vInt.length;
           recordInfo.elementSize = vInt.value;
           break;
         case BINARY:
           // using vint instead of 4 bytes
           LazyBinaryUtils.readVInt(bytes, offset, vInt);
           recordInfo.elementOffset = vInt.length;
           recordInfo.elementSize = vInt.value;
           break;
         case DATE:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = WritableUtils.decodeVIntSize(bytes[offset]);
           break;
         case TIMESTAMP:
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = TimestampWritable.getTotalLength(bytes, offset);
           break;
         case DECIMAL:
           // using vint instead of 4 bytes
           LazyBinaryUtils.readVInt(bytes, offset, vInt);
           recordInfo.elementOffset = 0;
           recordInfo.elementSize = vInt.length;
           LazyBinaryUtils.readVInt(bytes, offset + vInt.length, vInt);
           recordInfo.elementSize += vInt.length + vInt.value;
           break;
         default:
           {
             throw new RuntimeException("Unrecognized primitive type: " + primitiveCategory);
           }
       }
       break;
     case LIST:
     case MAP:
     case STRUCT:
     case UNION:
       recordInfo.elementOffset = 4;
       recordInfo.elementSize = LazyBinaryUtils.byteArrayToInt(bytes, offset);
       break;
     default:
       {
         throw new RuntimeException("Unrecognized non-primitive type: " + category);
       }
   }
 }
  static void serialize(OutputByteBuffer buffer, Object o, ObjectInspector oi, boolean invert) {
    // Is this field a null?
    if (o == null) {
      buffer.write((byte) 0, invert);
      return;
    }
    // This field is not a null.
    buffer.write((byte) 1, invert);

    switch (oi.getCategory()) {
      case PRIMITIVE:
        {
          PrimitiveObjectInspector poi = (PrimitiveObjectInspector) oi;
          switch (poi.getPrimitiveCategory()) {
            case VOID:
              {
                return;
              }
            case BOOLEAN:
              {
                boolean v = ((BooleanObjectInspector) poi).get(o);
                buffer.write((byte) (v ? 2 : 1), invert);
                return;
              }
            case BYTE:
              {
                ByteObjectInspector boi = (ByteObjectInspector) poi;
                byte v = boi.get(o);
                buffer.write((byte) (v ^ 0x80), invert);
                return;
              }
            case SHORT:
              {
                ShortObjectInspector spoi = (ShortObjectInspector) poi;
                short v = spoi.get(o);
                buffer.write((byte) ((v >> 8) ^ 0x80), invert);
                buffer.write((byte) v, invert);
                return;
              }
            case INT:
              {
                IntObjectInspector ioi = (IntObjectInspector) poi;
                int v = ioi.get(o);
                buffer.write((byte) ((v >> 24) ^ 0x80), invert);
                buffer.write((byte) (v >> 16), invert);
                buffer.write((byte) (v >> 8), invert);
                buffer.write((byte) v, invert);
                return;
              }
            case LONG:
              {
                LongObjectInspector loi = (LongObjectInspector) poi;
                long v = loi.get(o);
                buffer.write((byte) ((v >> 56) ^ 0x80), invert);
                buffer.write((byte) (v >> 48), invert);
                buffer.write((byte) (v >> 40), invert);
                buffer.write((byte) (v >> 32), invert);
                buffer.write((byte) (v >> 24), invert);
                buffer.write((byte) (v >> 16), invert);
                buffer.write((byte) (v >> 8), invert);
                buffer.write((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);
                }
                buffer.write((byte) (v >> 24), invert);
                buffer.write((byte) (v >> 16), invert);
                buffer.write((byte) (v >> 8), invert);
                buffer.write((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);
                }
                buffer.write((byte) (v >> 56), invert);
                buffer.write((byte) (v >> 48), invert);
                buffer.write((byte) (v >> 40), invert);
                buffer.write((byte) (v >> 32), invert);
                buffer.write((byte) (v >> 24), invert);
                buffer.write((byte) (v >> 16), invert);
                buffer.write((byte) (v >> 8), invert);
                buffer.write((byte) v, invert);
                return;
              }
            case STRING:
              {
                StringObjectInspector soi = (StringObjectInspector) poi;
                Text t = soi.getPrimitiveWritableObject(o);
                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;
                long v = doi.getPrimitiveWritableObject(o).getTimeInSeconds();
                buffer.write((byte) ((v >> 56) ^ 0x80), invert);
                buffer.write((byte) (v >> 48), invert);
                buffer.write((byte) (v >> 40), invert);
                buffer.write((byte) (v >> 32), invert);
                buffer.write((byte) (v >> 24), invert);
                buffer.write((byte) (v >> 16), invert);
                buffer.write((byte) (v >> 8), invert);
                buffer.write((byte) 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++) {
                  buffer.write(data[i], 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++) {
            buffer.write((byte) 1, invert);
            serialize(buffer, loi.getListElement(o, eid), eoi, invert);
          }
          // and \0 to terminate
          buffer.write((byte) 0, invert);
          return;
        }
      case MAP:
        {
          MapObjectInspector moi = (MapObjectInspector) oi;
          ObjectInspector koi = moi.getMapKeyObjectInspector();
          ObjectInspector voi = moi.getMapValueObjectInspector();

          // \1 followed by each key and then each value
          Map<?, ?> map = moi.getMap(o);
          for (Map.Entry<?, ?> entry : map.entrySet()) {
            buffer.write((byte) 1, invert);
            serialize(buffer, entry.getKey(), koi, invert);
            serialize(buffer, entry.getValue(), voi, invert);
          }
          // and \0 to terminate
          buffer.write((byte) 0, invert);
          return;
        }
      case STRUCT:
        {
          StructObjectInspector soi = (StructObjectInspector) oi;
          List<? extends StructField> fields = soi.getAllStructFieldRefs();

          for (int i = 0; i < fields.size(); i++) {
            serialize(
                buffer,
                soi.getStructFieldData(o, fields.get(i)),
                fields.get(i).getFieldObjectInspector(),
                invert);
          }
          return;
        }
      case UNION:
        {
          UnionObjectInspector uoi = (UnionObjectInspector) oi;
          byte tag = uoi.getTag(o);
          buffer.write(tag, invert);
          serialize(buffer, uoi.getField(o), uoi.getObjectInspectors().get(tag), invert);
          return;
        }
      default:
        {
          throw new RuntimeException("Unrecognized type: " + oi.getCategory());
        }
    }
  }
 public static Timestamp createTimestamp(byte[] bytes, int offset) {
   Timestamp t = new Timestamp(0);
   TimestampWritable.setTimestamp(t, bytes, offset);
   return t;
 }
  public static int hashCode(Object o, ObjectInspector objIns) {
    if (o == null) {
      return 0;
    }
    switch (objIns.getCategory()) {
      case PRIMITIVE:
        {
          PrimitiveObjectInspector poi = ((PrimitiveObjectInspector) objIns);
          switch (poi.getPrimitiveCategory()) {
            case VOID:
              return 0;
            case BOOLEAN:
              return ((BooleanObjectInspector) poi).get(o) ? 1 : 0;
            case BYTE:
              return ((ByteObjectInspector) poi).get(o);
            case SHORT:
              return ((ShortObjectInspector) poi).get(o);
            case INT:
              return ((IntObjectInspector) poi).get(o);
            case LONG:
              {
                long a = ((LongObjectInspector) poi).get(o);
                return (int) ((a >>> 32) ^ a);
              }
            case FLOAT:
              return Float.floatToIntBits(((FloatObjectInspector) poi).get(o));
            case DOUBLE:
              {
                // This hash function returns the same result as Double.hashCode()
                // while DoubleWritable.hashCode returns a different result.
                long a = Double.doubleToLongBits(((DoubleObjectInspector) poi).get(o));
                return (int) ((a >>> 32) ^ a);
              }
            case STRING:
              {
                // This hash function returns the same result as String.hashCode() when
                // all characters are ASCII, while Text.hashCode() always returns a
                // different result.
                Text t = ((StringObjectInspector) poi).getPrimitiveWritableObject(o);
                int r = 0;
                for (int i = 0; i < t.getLength(); i++) {
                  r = r * 31 + t.getBytes()[i];
                }
                return r;
              }
            case CHAR:
              return ((HiveCharObjectInspector) poi).getPrimitiveWritableObject(o).hashCode();
            case VARCHAR:
              return ((HiveVarcharObjectInspector) poi).getPrimitiveWritableObject(o).hashCode();
            case BINARY:
              return ((BinaryObjectInspector) poi).getPrimitiveWritableObject(o).hashCode();

            case DATE:
              return ((DateObjectInspector) poi).getPrimitiveWritableObject(o).hashCode();
            case TIMESTAMP:
              TimestampWritable t = ((TimestampObjectInspector) poi).getPrimitiveWritableObject(o);
              return t.hashCode();
            case INTERVAL_YEAR_MONTH:
              HiveIntervalYearMonthWritable intervalYearMonth =
                  ((HiveIntervalYearMonthObjectInspector) poi).getPrimitiveWritableObject(o);
              return intervalYearMonth.hashCode();
            case INTERVAL_DAY_TIME:
              HiveIntervalDayTimeWritable intervalDayTime =
                  ((HiveIntervalDayTimeObjectInspector) poi).getPrimitiveWritableObject(o);
              return intervalDayTime.hashCode();
            case DECIMAL:
              return ((HiveDecimalObjectInspector) poi).getPrimitiveWritableObject(o).hashCode();

            default:
              {
                throw new RuntimeException("Unknown type: " + poi.getPrimitiveCategory());
              }
          }
        }
      case LIST:
        {
          int r = 0;
          ListObjectInspector listOI = (ListObjectInspector) objIns;
          ObjectInspector elemOI = listOI.getListElementObjectInspector();
          for (int ii = 0; ii < listOI.getListLength(o); ++ii) {
            r = 31 * r + hashCode(listOI.getListElement(o, ii), elemOI);
          }
          return r;
        }
      case MAP:
        {
          int r = 0;
          MapObjectInspector mapOI = (MapObjectInspector) objIns;
          ObjectInspector keyOI = mapOI.getMapKeyObjectInspector();
          ObjectInspector valueOI = mapOI.getMapValueObjectInspector();
          Map<?, ?> map = mapOI.getMap(o);
          for (Map.Entry<?, ?> entry : map.entrySet()) {
            r += hashCode(entry.getKey(), keyOI) ^ hashCode(entry.getValue(), valueOI);
          }
          return r;
        }
      case STRUCT:
        int r = 0;
        StructObjectInspector structOI = (StructObjectInspector) objIns;
        List<? extends StructField> fields = structOI.getAllStructFieldRefs();
        for (StructField field : fields) {
          r =
              31 * r
                  + hashCode(
                      structOI.getStructFieldData(o, field), field.getFieldObjectInspector());
        }
        return r;

      case UNION:
        UnionObjectInspector uOI = (UnionObjectInspector) objIns;
        byte tag = uOI.getTag(o);
        return hashCode(uOI.getField(o), uOI.getObjectInspectors().get(tag));

      default:
        throw new RuntimeException("Unknown type: " + objIns.getTypeName());
    }
  }
  static Object deserialize(InputByteBuffer buffer, TypeInfo type, boolean invert, Object reuse)
      throws IOException {

    // Is this field a null?
    byte isNull = buffer.read(invert);
    if (isNull == 0) {
      return null;
    }
    assert (isNull == 1);

    switch (type.getCategory()) {
      case PRIMITIVE:
        {
          PrimitiveTypeInfo ptype = (PrimitiveTypeInfo) type;
          switch (ptype.getPrimitiveCategory()) {
            case VOID:
              {
                return null;
              }
            case BOOLEAN:
              {
                BooleanWritable r = reuse == null ? new BooleanWritable() : (BooleanWritable) reuse;
                byte b = buffer.read(invert);
                assert (b == 1 || b == 2);
                r.set(b == 2);
                return r;
              }
            case BYTE:
              {
                ByteWritable r = reuse == null ? new ByteWritable() : (ByteWritable) reuse;
                r.set((byte) (buffer.read(invert) ^ 0x80));
                return r;
              }
            case SHORT:
              {
                ShortWritable r = reuse == null ? new ShortWritable() : (ShortWritable) reuse;
                int v = buffer.read(invert) ^ 0x80;
                v = (v << 8) + (buffer.read(invert) & 0xff);
                r.set((short) v);
                return r;
              }
            case INT:
              {
                IntWritable r = reuse == null ? new IntWritable() : (IntWritable) reuse;
                int v = buffer.read(invert) ^ 0x80;
                for (int i = 0; i < 3; i++) {
                  v = (v << 8) + (buffer.read(invert) & 0xff);
                }
                r.set(v);
                return r;
              }
            case LONG:
              {
                LongWritable r = reuse == null ? new LongWritable() : (LongWritable) reuse;
                long v = buffer.read(invert) ^ 0x80;
                for (int i = 0; i < 7; i++) {
                  v = (v << 8) + (buffer.read(invert) & 0xff);
                }
                r.set(v);
                return r;
              }
            case FLOAT:
              {
                FloatWritable r = reuse == null ? new FloatWritable() : (FloatWritable) reuse;
                int v = 0;
                for (int i = 0; i < 4; i++) {
                  v = (v << 8) + (buffer.read(invert) & 0xff);
                }
                if ((v & (1 << 31)) == 0) {
                  // negative number, flip all bits
                  v = ~v;
                } else {
                  // positive number, flip the first bit
                  v = v ^ (1 << 31);
                }
                r.set(Float.intBitsToFloat(v));
                return r;
              }
            case DOUBLE:
              {
                DoubleWritable r = reuse == null ? new DoubleWritable() : (DoubleWritable) reuse;
                long v = 0;
                for (int i = 0; i < 8; i++) {
                  v = (v << 8) + (buffer.read(invert) & 0xff);
                }
                if ((v & (1L << 63)) == 0) {
                  // negative number, flip all bits
                  v = ~v;
                } else {
                  // positive number, flip the first bit
                  v = v ^ (1L << 63);
                }
                r.set(Double.longBitsToDouble(v));
                return r;
              }
            case STRING:
              {
                Text r = reuse == null ? new Text() : (Text) reuse;
                // Get the actual length first
                int start = buffer.tell();
                int length = 0;
                do {
                  byte b = buffer.read(invert);
                  if (b == 0) {
                    // end of string
                    break;
                  }
                  if (b == 1) {
                    // the last char is an escape char. read the actual char
                    buffer.read(invert);
                  }
                  length++;
                } while (true);

                if (length == buffer.tell() - start) {
                  // No escaping happened, so we are already done.
                  r.set(buffer.getData(), start, length);
                } else {
                  // Escaping happened, we need to copy byte-by-byte.
                  // 1. Set the length first.
                  r.set(buffer.getData(), start, length);
                  // 2. Reset the pointer.
                  buffer.seek(start);
                  // 3. Copy the data.
                  byte[] rdata = r.getBytes();
                  for (int i = 0; i < length; i++) {
                    byte b = buffer.read(invert);
                    if (b == 1) {
                      // The last char is an escape char, read the actual char.
                      // The serialization format escape \0 to \1, and \1 to \2,
                      // to make sure the string is null-terminated.
                      b = (byte) (buffer.read(invert) - 1);
                    }
                    rdata[i] = b;
                  }
                  // 4. Read the null terminator.
                  byte b = buffer.read(invert);
                  assert (b == 0);
                }
                return r;
              }

            case BINARY:
              {
                BytesWritable bw = new BytesWritable();
                // Get the actual length first
                int start = buffer.tell();
                int length = 0;
                do {
                  byte b = buffer.read(invert);
                  if (b == 0) {
                    // end of string
                    break;
                  }
                  if (b == 1) {
                    // the last char is an escape char. read the actual char
                    buffer.read(invert);
                  }
                  length++;
                } while (true);

                if (length == buffer.tell() - start) {
                  // No escaping happened, so we are already done.
                  bw.set(buffer.getData(), start, length);
                } else {
                  // Escaping happened, we need to copy byte-by-byte.
                  // 1. Set the length first.
                  bw.set(buffer.getData(), start, length);
                  // 2. Reset the pointer.
                  buffer.seek(start);
                  // 3. Copy the data.
                  byte[] rdata = bw.getBytes();
                  for (int i = 0; i < length; i++) {
                    byte b = buffer.read(invert);
                    if (b == 1) {
                      // The last char is an escape char, read the actual char.
                      // The serialization format escape \0 to \1, and \1 to \2,
                      // to make sure the string is null-terminated.
                      b = (byte) (buffer.read(invert) - 1);
                    }
                    rdata[i] = b;
                  }
                  // 4. Read the null terminator.
                  byte b = buffer.read(invert);
                  assert (b == 0);
                }
                return bw;
              }

            case DATE:
              {
                DateWritable d = reuse == null ? new DateWritable() : (DateWritable) reuse;
                long v = buffer.read(invert) ^ 0x80;
                for (int i = 0; i < 7; i++) {
                  v = (v << 8) + (buffer.read(invert) & 0xff);
                }
                d.set(DateWritable.timeToDate(v));
                return d;
              }

            case TIMESTAMP:
              TimestampWritable t =
                  (reuse == null ? new TimestampWritable() : (TimestampWritable) reuse);
              byte[] bytes = new byte[8];

              for (int i = 0; i < bytes.length; i++) {
                bytes[i] = buffer.read(invert);
              }
              t.setBinarySortable(bytes, 0);
              return t;

            default:
              {
                throw new RuntimeException("Unrecognized type: " + ptype.getPrimitiveCategory());
              }
          }
        }
      case LIST:
        {
          ListTypeInfo ltype = (ListTypeInfo) type;
          TypeInfo etype = ltype.getListElementTypeInfo();

          // Create the list if needed
          ArrayList<Object> r = reuse == null ? new ArrayList<Object>() : (ArrayList<Object>) reuse;

          // Read the list
          int size = 0;
          while (true) {
            int more = buffer.read(invert);
            if (more == 0) {
              // \0 to terminate
              break;
            }
            // \1 followed by each element
            assert (more == 1);
            if (size == r.size()) {
              r.add(null);
            }
            r.set(size, deserialize(buffer, etype, invert, r.get(size)));
            size++;
          }
          // Remove additional elements if the list is reused
          while (r.size() > size) {
            r.remove(r.size() - 1);
          }
          return r;
        }
      case MAP:
        {
          MapTypeInfo mtype = (MapTypeInfo) type;
          TypeInfo ktype = mtype.getMapKeyTypeInfo();
          TypeInfo vtype = mtype.getMapValueTypeInfo();

          // Create the map if needed
          Map<Object, Object> r;
          if (reuse == null) {
            r = new HashMap<Object, Object>();
          } else {
            r = (HashMap<Object, Object>) reuse;
            r.clear();
          }

          while (true) {
            int more = buffer.read(invert);
            if (more == 0) {
              // \0 to terminate
              break;
            }
            // \1 followed by each key and then each value
            assert (more == 1);
            Object k = deserialize(buffer, ktype, invert, null);
            Object v = deserialize(buffer, vtype, invert, null);
            r.put(k, v);
          }
          return r;
        }
      case STRUCT:
        {
          StructTypeInfo stype = (StructTypeInfo) type;
          List<TypeInfo> fieldTypes = stype.getAllStructFieldTypeInfos();
          int size = fieldTypes.size();
          // Create the struct if needed
          ArrayList<Object> r =
              reuse == null ? new ArrayList<Object>(size) : (ArrayList<Object>) reuse;
          assert (r.size() <= size);
          // Set the size of the struct
          while (r.size() < size) {
            r.add(null);
          }
          // Read one field by one field
          for (int eid = 0; eid < size; eid++) {
            r.set(eid, deserialize(buffer, fieldTypes.get(eid), invert, r.get(eid)));
          }
          return r;
        }
      case UNION:
        {
          UnionTypeInfo utype = (UnionTypeInfo) type;
          StandardUnion r = reuse == null ? new StandardUnion() : (StandardUnion) reuse;
          // Read the tag
          byte tag = buffer.read(invert);
          r.setTag(tag);
          r.setObject(
              deserialize(buffer, utype.getAllUnionObjectTypeInfos().get(tag), invert, null));
          return r;
        }
      default:
        {
          throw new RuntimeException("Unrecognized type: " + type.getCategory());
        }
    }
  }
 public TimestampWritable(TimestampWritable t) {
   this(t.getBytes(), 0);
 }
  /** Compare two objects with their respective ObjectInspectors. */
  public static int compare(
      Object o1,
      ObjectInspector oi1,
      Object o2,
      ObjectInspector oi2,
      MapEqualComparer mapEqualComparer) {
    if (oi1.getCategory() != oi2.getCategory()) {
      return oi1.getCategory().compareTo(oi2.getCategory());
    }

    if (o1 == null) {
      return o2 == null ? 0 : -1;
    } else if (o2 == null) {
      return 1;
    }

    switch (oi1.getCategory()) {
      case PRIMITIVE:
        {
          PrimitiveObjectInspector poi1 = ((PrimitiveObjectInspector) oi1);
          PrimitiveObjectInspector poi2 = ((PrimitiveObjectInspector) oi2);
          if (poi1.getPrimitiveCategory() != poi2.getPrimitiveCategory()) {
            return poi1.getPrimitiveCategory().compareTo(poi2.getPrimitiveCategory());
          }
          switch (poi1.getPrimitiveCategory()) {
            case VOID:
              return 0;
            case BOOLEAN:
              {
                int v1 = ((BooleanObjectInspector) poi1).get(o1) ? 1 : 0;
                int v2 = ((BooleanObjectInspector) poi2).get(o2) ? 1 : 0;
                return v1 - v2;
              }
            case BYTE:
              {
                int v1 = ((ByteObjectInspector) poi1).get(o1);
                int v2 = ((ByteObjectInspector) poi2).get(o2);
                return v1 - v2;
              }
            case SHORT:
              {
                int v1 = ((ShortObjectInspector) poi1).get(o1);
                int v2 = ((ShortObjectInspector) poi2).get(o2);
                return v1 - v2;
              }
            case INT:
              {
                int v1 = ((IntObjectInspector) poi1).get(o1);
                int v2 = ((IntObjectInspector) poi2).get(o2);
                return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
              }
            case LONG:
              {
                long v1 = ((LongObjectInspector) poi1).get(o1);
                long v2 = ((LongObjectInspector) poi2).get(o2);
                return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
              }
            case FLOAT:
              {
                float v1 = ((FloatObjectInspector) poi1).get(o1);
                float v2 = ((FloatObjectInspector) poi2).get(o2);
                return Float.compare(v1, v2);
              }
            case DOUBLE:
              {
                double v1 = ((DoubleObjectInspector) poi1).get(o1);
                double v2 = ((DoubleObjectInspector) poi2).get(o2);
                return Double.compare(v1, v2);
              }
            case STRING:
              {
                if (poi1.preferWritable() || poi2.preferWritable()) {
                  Text t1 = (Text) poi1.getPrimitiveWritableObject(o1);
                  Text t2 = (Text) poi2.getPrimitiveWritableObject(o2);
                  return t1 == null ? (t2 == null ? 0 : -1) : (t2 == null ? 1 : t1.compareTo(t2));
                } else {
                  String s1 = (String) poi1.getPrimitiveJavaObject(o1);
                  String s2 = (String) poi2.getPrimitiveJavaObject(o2);
                  return s1 == null ? (s2 == null ? 0 : -1) : (s2 == null ? 1 : s1.compareTo(s2));
                }
              }
            case CHAR:
              {
                HiveCharWritable t1 =
                    ((HiveCharObjectInspector) poi1).getPrimitiveWritableObject(o1);
                HiveCharWritable t2 =
                    ((HiveCharObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return t1.compareTo(t2);
              }
            case VARCHAR:
              {
                HiveVarcharWritable t1 =
                    ((HiveVarcharObjectInspector) poi1).getPrimitiveWritableObject(o1);
                HiveVarcharWritable t2 =
                    ((HiveVarcharObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return t1.compareTo(t2);
              }
            case BINARY:
              {
                BytesWritable bw1 = ((BinaryObjectInspector) poi1).getPrimitiveWritableObject(o1);
                BytesWritable bw2 = ((BinaryObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return bw1.compareTo(bw2);
              }

            case DATE:
              {
                DateWritable d1 = ((DateObjectInspector) poi1).getPrimitiveWritableObject(o1);
                DateWritable d2 = ((DateObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return d1.compareTo(d2);
              }
            case TIMESTAMP:
              {
                TimestampWritable t1 =
                    ((TimestampObjectInspector) poi1).getPrimitiveWritableObject(o1);
                TimestampWritable t2 =
                    ((TimestampObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return t1.compareTo(t2);
              }
            case INTERVAL_YEAR_MONTH:
              {
                HiveIntervalYearMonthWritable i1 =
                    ((HiveIntervalYearMonthObjectInspector) poi1).getPrimitiveWritableObject(o1);
                HiveIntervalYearMonthWritable i2 =
                    ((HiveIntervalYearMonthObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return i1.compareTo(i2);
              }
            case INTERVAL_DAY_TIME:
              {
                HiveIntervalDayTimeWritable i1 =
                    ((HiveIntervalDayTimeObjectInspector) poi1).getPrimitiveWritableObject(o1);
                HiveIntervalDayTimeWritable i2 =
                    ((HiveIntervalDayTimeObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return i1.compareTo(i2);
              }
            case DECIMAL:
              {
                HiveDecimalWritable t1 =
                    ((HiveDecimalObjectInspector) poi1).getPrimitiveWritableObject(o1);
                HiveDecimalWritable t2 =
                    ((HiveDecimalObjectInspector) poi2).getPrimitiveWritableObject(o2);
                return t1.compareTo(t2);
              }
            default:
              {
                throw new RuntimeException("Unknown type: " + poi1.getPrimitiveCategory());
              }
          }
        }
      case STRUCT:
        {
          StructObjectInspector soi1 = (StructObjectInspector) oi1;
          StructObjectInspector soi2 = (StructObjectInspector) oi2;
          List<? extends StructField> fields1 = soi1.getAllStructFieldRefs();
          List<? extends StructField> fields2 = soi2.getAllStructFieldRefs();
          int minimum = Math.min(fields1.size(), fields2.size());
          for (int i = 0; i < minimum; i++) {
            int r =
                compare(
                    soi1.getStructFieldData(o1, fields1.get(i)),
                    fields1.get(i).getFieldObjectInspector(),
                    soi2.getStructFieldData(o2, fields2.get(i)),
                    fields2.get(i).getFieldObjectInspector(),
                    mapEqualComparer);
            if (r != 0) {
              return r;
            }
          }
          return fields1.size() - fields2.size();
        }
      case LIST:
        {
          ListObjectInspector loi1 = (ListObjectInspector) oi1;
          ListObjectInspector loi2 = (ListObjectInspector) oi2;
          int minimum = Math.min(loi1.getListLength(o1), loi2.getListLength(o2));
          for (int i = 0; i < minimum; i++) {
            int r =
                compare(
                    loi1.getListElement(o1, i),
                    loi1.getListElementObjectInspector(),
                    loi2.getListElement(o2, i),
                    loi2.getListElementObjectInspector(),
                    mapEqualComparer);
            if (r != 0) {
              return r;
            }
          }
          return loi1.getListLength(o1) - loi2.getListLength(o2);
        }
      case MAP:
        {
          if (mapEqualComparer == null) {
            throw new RuntimeException("Compare on map type not supported!");
          } else {
            return mapEqualComparer.compare(
                o1, (MapObjectInspector) oi1, o2, (MapObjectInspector) oi2);
          }
        }
      case UNION:
        {
          UnionObjectInspector uoi1 = (UnionObjectInspector) oi1;
          UnionObjectInspector uoi2 = (UnionObjectInspector) oi2;
          byte tag1 = uoi1.getTag(o1);
          byte tag2 = uoi2.getTag(o2);
          if (tag1 != tag2) {
            return tag1 - tag2;
          }
          return compare(
              uoi1.getField(o1),
              uoi1.getObjectInspectors().get(tag1),
              uoi2.getField(o2),
              uoi2.getObjectInspectors().get(tag2),
              mapEqualComparer);
        }
      default:
        throw new RuntimeException("Compare on unknown type: " + oi1.getCategory());
    }
  }