private static TimestampWritableV2 serializeDeserializeAndCheckTimestamp(Timestamp ts)
      throws IOException {
    TimestampWritableV2 tsw = new TimestampWritableV2(ts);
    assertEquals(ts, tsw.getTimestamp());

    byte[] tsBytes = serializeToBytes(tsw);
    TimestampWritableV2 deserTSW = deserializeFromBytes(tsBytes);
    assertTSWEquals(tsw, deserTSW);
    assertEquals(ts, deserTSW.getTimestamp());
    assertEquals(tsBytes.length, tsw.getTotalLength());

    // Also convert to/from binary-sortable representation.
    int binarySortableOffset = Math.abs(tsw.hashCode()) % 10;
    byte[] binarySortableBytes = padBytes(tsw.getBinarySortable(), binarySortableOffset);
    TimestampWritableV2 fromBinSort = new TimestampWritableV2();
    fromBinSort.setBinarySortable(binarySortableBytes, binarySortableOffset);
    assertTSWEquals(tsw, fromBinSort);

    long timeSeconds = ts.toEpochSecond();
    if (0 <= timeSeconds && timeSeconds <= Integer.MAX_VALUE) {
      assertEquals(Timestamp.ofEpochSecond(timeSeconds),
        fromIntAndVInts((int) timeSeconds, 0).getTimestamp());

      int nanos = reverseNanos(ts.getNanos());
      assertEquals(ts,
        fromIntAndVInts((int) timeSeconds | (nanos != 0 ? HAS_DECIMAL_MASK : 0),
          nanos).getTimestamp());
    }

    assertEquals(ts.getNanos(), tsw.getNanos());
    assertEquals(getSeconds(ts), tsw.getSeconds());

    // Test various set methods and copy constructors.
    {
      TimestampWritableV2 tsSet1 = new TimestampWritableV2();
      // make the offset non-zero to keep things interesting.
      int offset = Math.abs(ts.hashCode() % 32);
      byte[] shiftedBytes = padBytes(tsBytes, offset);
      tsSet1.set(shiftedBytes, offset);
      assertTSWEquals(tsw, tsSet1);

      TimestampWritableV2 tswShiftedBytes = new TimestampWritableV2(shiftedBytes, offset);
      assertTSWEquals(tsw, tswShiftedBytes);
      assertTSWEquals(tsw, deserializeFromBytes(serializeToBytes(tswShiftedBytes)));
    }

    {
      TimestampWritableV2 tsSet2 = new TimestampWritableV2();
      tsSet2.set(ts);
      assertTSWEquals(tsw, tsSet2);
    }

    {
      TimestampWritableV2 tsSet3 = new TimestampWritableV2();
      tsSet3.set(tsw);
      assertTSWEquals(tsw, tsSet3);
    }

    {
      TimestampWritableV2 tsSet4 = new TimestampWritableV2();
      tsSet4.set(deserTSW);
      assertTSWEquals(tsw, tsSet4);
    }

    double expectedDbl = getSeconds(ts) + 1e-9d * ts.getNanos();
    assertTrue(Math.abs(tsw.getDouble() - expectedDbl) < 1e-10d);

    return deserTSW;
  }
Pad the given byte array with the given number of bytes in the beginning. The padding bytes
deterministically depend on the passed data.
serde/src/test/org/apache/hadoop/hive/serde2/io/TestTimestampWritableV2.java