/**
  * @return byte[] representation of TimestampWritable that is binary sortable (7 bytes for
  *     seconds, 4 bytes for nanoseconds)
  */
 public byte[] getBinarySortable() {
   byte[] b = new byte[BINARY_SORTABLE_LENGTH];
   int nanos = getNanos();
   // We flip the highest-order bit of the seven-byte representation of seconds to make negative
   // values come before positive ones.
   long seconds = getSeconds() ^ SEVEN_BYTE_LONG_SIGN_FLIP;
   sevenByteLongToBytes(seconds, b, 0);
   intToBytes(nanos, b, 7);
   return b;
 }
  /**
   * Writes a Timestamp's serialized value to byte array b at the given offset
   *
   * @param timestamp to convert to bytes
   * @param b destination byte array
   * @param offset destination offset in the byte array
   */
  public static void convertTimestampToBytes(Timestamp t, byte[] b, int offset) {
    long millis = t.getTime();
    int nanos = t.getNanos();

    long seconds = millisToSeconds(millis);
    boolean hasSecondVInt = seconds < 0 || seconds > Integer.MAX_VALUE;
    boolean hasDecimal = setNanosBytes(nanos, b, offset + 4, hasSecondVInt);

    int firstInt = (int) seconds;
    if (hasDecimal || hasSecondVInt) {
      firstInt |= DECIMAL_OR_SECOND_VINT_FLAG;
    } else {
      firstInt &= LOWEST_31_BITS_OF_SEC_MASK;
    }
    intToBytes(firstInt, b, offset);

    if (hasSecondVInt) {
      LazyBinaryUtils.writeVLongToByteArray(
          b, offset + 4 + WritableUtils.decodeVIntSize(b[offset + 4]), seconds >> 31);
    }
  }
  /**
   * Given a byte[] that has binary sortable data, initialize the internal structures to hold that
   * data
   *
   * @param bytes the byte array that holds the binary sortable representation
   * @param binSortOffset offset of the binary-sortable representation within the buffer.
   */
  public void setBinarySortable(byte[] bytes, int binSortOffset) {
    // Flip the sign bit (and unused bits of the high-order byte) of the seven-byte long back.
    long seconds = readSevenByteLong(bytes, binSortOffset) ^ SEVEN_BYTE_LONG_SIGN_FLIP;
    int nanos = bytesToInt(bytes, binSortOffset + 7);
    int firstInt = (int) seconds;
    boolean hasSecondVInt = seconds < 0 || seconds > Integer.MAX_VALUE;
    if (nanos != 0 || hasSecondVInt) {
      firstInt |= DECIMAL_OR_SECOND_VINT_FLAG;
    } else {
      firstInt &= LOWEST_31_BITS_OF_SEC_MASK;
    }

    intToBytes(firstInt, internalBytes, 0);
    setNanosBytes(nanos, internalBytes, 4, hasSecondVInt);
    if (hasSecondVInt) {
      LazyBinaryUtils.writeVLongToByteArray(
          internalBytes, 4 + WritableUtils.decodeVIntSize(internalBytes[4]), seconds >> 31);
    }

    currentBytes = internalBytes;
    this.offset = 0;
  }