parquet-common/src/main/java/org/apache/parquet/bytes/BytesUtils.java
public static long readZigZagVarLong(InputStream in) throws IOException {
    long raw = readUnsignedVarLong(in);
    long temp = (((raw << 63) >> 63) ^ raw) >> 1;
    return temp ^ (raw & (1L << 63));
  }
public static long readZigZagVarLong(InputStream in) throws IOException {
    long raw = readUnsignedVarLong(in);
    long temp = (((raw << 63) >> 63) ^ raw) >> 1;
    return temp ^ (raw & (1L << 63));
  }
uses a trick mentioned in https://developers.google.com/protocol-buffers/docs/encoding to read zigZag encoded data
TODO: the implementation is compatible with readZigZagVarInt. Is there a need for different functions?
@param in an input stream
@return the value of a zig-zag var-long read from the current position in the stream
@throws IOException if there is an exception while reading