All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.clickzetta.platform.operator.Bytes Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
package com.clickzetta.platform.operator;

import com.clickzetta.platform.util.DecimalUtil;
import com.clickzetta.platform.util.Slice;
import com.google.common.io.BaseEncoding;
import io.netty.buffer.ByteBuf;
import io.netty.util.CharsetUtil;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Comparator;

public final class Bytes {

  private static final BigInteger TWO_COMPL_REF = BigInteger.ONE.shiftLeft(64);

  private static final BigInteger BIGINT32_MAX = BigInteger.valueOf(Integer.MAX_VALUE);
  private static final BigInteger BIGINT32_MIN = BigInteger.valueOf(Integer.MIN_VALUE);
  private static final BigInteger BIGINT64_MAX = BigInteger.valueOf(Long.MAX_VALUE);
  private static final BigInteger BIGINT64_MIN = BigInteger.valueOf(Long.MIN_VALUE);

  private Bytes() {
  }


  public static boolean getBoolean(final byte[] b) {
    byte v = getByte(b, 0);
    return v == 1;
  }


  public static boolean getBoolean(final byte[] b, final int offset) {
    byte v = getByte(b, offset);
    return v == 1;
  }


  public static byte getByte(final byte[] b) {
    return getByte(b, 0);
  }


  public static byte getByte(final byte[] b, final int offset) {
    return b[offset];
  }


  public static short getUnsignedByte(final byte[] b) {
    return getUnsignedByte(b, 0);
  }


  public static short getUnsignedByte(final byte[] b, final int offset) {
    return (short) (b[offset] & 0x00FF);
  }


  public static void setUnsignedByte(final byte[] b, final short n) {
    setUnsignedByte(b, n, 0);
  }


  public static void setUnsignedByte(final byte[] b, final short n,
                                      final int offset) {
    b[offset] = (byte) n;
  }


  public static byte[] fromUnsignedByte(final short n) {
    final byte[] b = new byte[1];
    setUnsignedByte(b, n);
    return b;
  }


  public static short getShort(final byte[] b) {
    return getShort(b, 0);
  }


  public static short getShort(final byte[] b, final int offset) {
    return (short) ((b[offset] & 0xFF) | (b[offset + 1] << 8));
  }

  public static int getUnsignedShort(final byte[] b) {
    return getUnsignedShort(b, 0);
  }


  public static int getUnsignedShort(final byte[] b, final int offset) {
    return getShort(b, offset) & 0x0000FFFF;
  }


  public static void setShort(final byte[] b, final short n) {
    setShort(b, n, 0);
  }


  public static void setShort(final byte[] b, final short n,
                              final int offset) {
    b[offset + 0] = (byte) (n >>> 0);
    b[offset + 1] = (byte) (n >>> 8);
  }


  public static void setUnsignedShort(final byte[] b, final int n) {
    setUnsignedShort(b, n, 0);
  }


  public static void setUnsignedShort(final byte[] b, final int n,
                              final int offset) {
    b[offset + 0] = (byte) (n >>> 0);
    b[offset + 1] = (byte) (n >>> 8);
  }


  public static byte[] fromShort(final short n) {
    final byte[] b = new byte[2];
    setShort(b, n);
    return b;
  }


  public static byte[] fromUnsignedShort(final int n) {
    final byte[] b = new byte[2];
    setUnsignedShort(b, n);
    return b;
  }

  public static int getInt(final byte[] b) {
    return getInt(b, 0);
  }


  public static int getInt(final byte[] b, final int offset) {
    return (b[offset + 0] & 0xFF) << 0 |
        (b[offset + 1] & 0xFF) << 8 |
        (b[offset + 2] & 0xFF) << 16 |
        (b[offset + 3] & 0xFF) << 24;
  }


  public static long getUnsignedInt(final byte[] b) {
    return getUnsignedInt(b, 0);
  }

  public static long getUnsignedInt(final byte[] b, final int offset) {
    return getInt(b, offset) & 0x00000000FFFFFFFFL;
  }


  public static void setInt(final byte[] b, final int n) {
    setInt(b, n, 0);
  }


  public static void setInt(final byte[] b, final int n, final int offset) {
    b[offset + 0] = (byte) (n >>> 0);
    b[offset + 1] = (byte) (n >>> 8);
    b[offset + 2] = (byte) (n >>>  16);
    b[offset + 3] = (byte) (n >>>  24);
  }


  public static void setUnsignedInt(final byte[] b, final long n) {
    setUnsignedInt(b, n, 0);
  }


  public static void setUnsignedInt(final byte[] b, final long n, final int offset) {
    b[offset + 0] = (byte) (n >>> 0);
    b[offset + 1] = (byte) (n >>> 8);
    b[offset + 2] = (byte) (n >>>  16);
    b[offset + 3] = (byte) (n >>>  24);
  }

  public static void putVarInt32(final ByteBuffer b, final int v) {
    int bee = 128;
    if (v < (1 << 7)) {
      b.put((byte)v);
    } else if (v < (1 << 14)) {
      b.put((byte)(v | bee));
      b.put((byte)((v >> 7) | bee));
    } else if (v < (1 << 21)) {
      b.put((byte)(v | bee));
      b.put((byte)((v >> 7) | bee));
      b.put((byte)(v >> 14));
    } else if (v < (1 << 28)) {
      b.put((byte)(v | bee));
      b.put((byte)((v >> 7) | bee));
      b.put((byte)((v >> 14) | bee));
      b.put((byte)(v >> 21));
    } else {
      b.put((byte)(v | bee));
      b.put((byte)((v >> 7) | bee));
      b.put((byte)((v >> 14) | bee));
      b.put((byte)((v >> 21) | bee));
      b.put((byte)(v >> 28));
    }
  }


  static int readVarInt32(final ByteBuf buf) {
    int result = buf.readByte();
    if (result >= 0) {
      return result;
    }
    result &= 0x7F;
    result |= buf.readByte() << 7;
    if (result >= 0) {
      return result;
    }
    result &= 0x3FFF;
    result |= buf.readByte() << 14;
    if (result >= 0) {
      return result;
    }
    result &= 0x1FFFFF;
    result |= buf.readByte() << 21;
    if (result >= 0) {
      return result;
    }
    result &= 0x0FFFFFFF;
    final byte b = buf.readByte();
    result |= b << 28;
    if (b >= 0) {
      return result;
    }
    throw new IllegalArgumentException("Not a 32 bit varint: " + result +
        " (5th byte: " + b + ")");
  }

  public static byte[] fromBoolean(final boolean n) {
    final byte[] b = new byte[1];
    b[0] = (byte) (n ? 1 : 0);
    return b;
  }


  public static byte[] fromInt(final int n) {
    final byte[] b = new byte[4];
    setInt(b, n);
    return b;
  }


  public static byte[] fromUnsignedInt(final long n) {
    final byte[] b = new byte[4];
    setUnsignedInt(b, n);
    return b;
  }


  public static BigInteger getUnsignedLong(final byte[] b) {
    return getUnsignedLong(b, 0);
  }


  public static BigInteger getUnsignedLong(final byte[] b, final int offset) {
    long l = getLong(b, offset);
    BigInteger bi = BigInteger.valueOf(l);
    if (bi.compareTo(BigInteger.ZERO) < 0) {
      bi = bi.add(TWO_COMPL_REF);
    }
    return bi;
  }


  public static long getLong(final byte[] b) {
    return getLong(b, 0);
  }


  public static long getLong(final byte[] b, final int offset) {
    return (b[offset + 0] & 0xFFL) << 0 |
        (b[offset + 1] & 0xFFL) << 8 |
        (b[offset + 2] & 0xFFL) << 16 |
        (b[offset + 3] & 0xFFL) << 24 |
        (b[offset + 4] & 0xFFL) << 32 |
        (b[offset + 5] & 0xFFL) << 40 |
        (b[offset + 6] & 0xFFL) << 48 |
        (b[offset + 7] & 0xFFL) << 56;
  }


  public static void setLong(final byte[] b, final long n) {
    setLong(b, n, 0);
  }


  public static void setLong(final byte[] b, final long n, final int offset) {
    b[offset + 0] = (byte) (n >>> 0);
    b[offset + 1] = (byte) (n >>> 8);
    b[offset + 2] = (byte) (n >>> 16);
    b[offset + 3] = (byte) (n >>> 24);
    b[offset + 4] = (byte) (n >>> 32);
    b[offset + 5] = (byte) (n >>> 40);
    b[offset + 6] = (byte) (n >>>  48);
    b[offset + 7] = (byte) (n >>>  56);
  }


  public static void setUnsignedLong(final byte[] b, final BigInteger n) {
    setUnsignedLong(b, n, 0);
  }


  public static void setUnsignedLong(final byte[] b, final BigInteger n, final int offset) {
    setLong(b, n.longValue(), offset);
  }


  public static byte[] fromLong(final long n) {
    final byte[] b = new byte[8];
    setLong(b, n);
    return b;
  }


  public static byte[] fromUnsignedLong(final BigInteger n) {
    final byte[] b = new byte[8];
    setUnsignedLong(b, n);
    return b;
  }


  public static BigInteger getBigInteger(final byte[] b) {
    return getBigInteger(b, 0);
  }


  public static BigInteger getBigInteger(final byte[] b, final int offset) {
    byte[] bytes = Arrays.copyOfRange(b, offset, offset + 16);
    reverseBytes(bytes);
    return new BigInteger(bytes);
  }


  public static void setBigInteger(final byte[] b, final BigInteger n) {
    setBigInteger(b, n, 0);
  }


  public static void setBigInteger(final byte[] b, final BigInteger n, final int offset) {
    byte[] bytes = n.toByteArray();

    if (bytes.length > 16) {
      throw new IllegalArgumentException("Value is larger than the maximum 16 bytes: " + n);
    }

    reverseBytes(bytes);
    System.arraycopy(bytes, 0, b, offset, bytes.length);
    if (n.compareTo(BigInteger.ZERO) < 0) {
      Arrays.fill(b, offset + bytes.length, offset + 16, (byte) 0xff);
    }
  }


  public static byte[] fromBigInteger(final BigInteger n) {
    final byte[] b = new byte[16];
    setBigInteger(b, n);
    return b;
  }


  private static void reverseBytes(final byte[] b) {
    for (int i = 0; i < b.length / 2; i++) {
      byte temp = b[i];
      b[i] = b[b.length - i - 1];
      b[b.length - i - 1] = temp;
    }
  }


  public static float getFloat(final byte[] b) {
    return getFloat(b, 0);
  }


  public static float getFloat(final byte[] b, final int offset) {
    return Float.intBitsToFloat(getInt(b, offset));
  }


  public static void setFloat(final byte[] b, final float n) {
    setFloat(b, n, 0);
  }


  public static void setFloat(final byte[] b, final float n, final int offset) {
    setInt(b, Float.floatToIntBits(n), offset);
  }


  public static byte[] fromFloat(float n) {
    byte[] b = new byte[4];
    setFloat(b, n);
    return b;
  }


  public static double getDouble(final byte[] b) {
    return getDouble(b, 0);
  }


  public static double getDouble(final byte[] b, final int offset) {
    return Double.longBitsToDouble(getLong(b, offset));
  }


  public static void setDouble(final byte[] b, final double n) {
    setDouble(b, n, 0);
  }


  public static void setDouble(final byte[] b, final double n, final int offset) {
    setLong(b, Double.doubleToLongBits(n), offset);
  }


  public static byte[] fromDouble(double n) {
    byte[] b = new byte[8];
    setDouble(b, n);
    return b;
  }


  public static BigDecimal getDecimal(final byte[] b, int precision, int scale) {
    return getDecimal(b, 0, precision, scale);
  }


  public static BigDecimal getDecimal(final byte[] b, final int offset, int precision, int scale) {
    int size = DecimalUtil.precisionToSize(precision);
    switch (size) {
      case  DecimalUtil.DECIMAL32_SIZE:
        int intVal = getInt(b, offset);
        return BigDecimal.valueOf(intVal, scale);
      case DecimalUtil.DECIMAL64_SIZE:
        long longVal = getLong(b, offset);
        return BigDecimal.valueOf(longVal, scale);
      case DecimalUtil.DECIMAL128_SIZE:
        BigInteger int128Val = getBigInteger(b, offset);
        return new BigDecimal(int128Val, scale);
      default:
        throw new IllegalArgumentException("Unsupported decimal type size: " + size);
    }
  }


  public static void setBigDecimal(final byte[] b,  final BigDecimal n, int precision) {
    setBigDecimal(b, n, precision, 0);
  }


  public static void setBigDecimal(final byte[] b, final BigDecimal n, int precision,
                                   final int offset) {
    int size = DecimalUtil.precisionToSize(precision);
    BigInteger bigInt = n.unscaledValue();
    switch (size) {
      case  DecimalUtil.DECIMAL32_SIZE:
        if (bigInt.compareTo(BIGINT32_MIN) >= 0 && bigInt.compareTo(BIGINT32_MAX) <= 0) {
          setInt(b, bigInt.intValue(), offset);
        } else {
          throw new ArithmeticException("BigInteger out of int range");
        }
        break;
      case DecimalUtil.DECIMAL64_SIZE:
        if (bigInt.compareTo(BIGINT64_MIN) >= 0 && bigInt.compareTo(BIGINT64_MAX) <= 0) {
          setLong(b, bigInt.longValue(), offset);
        } else {
          throw new ArithmeticException("BigInteger out of int range");
        }
        break;
      case DecimalUtil.DECIMAL128_SIZE:
        setBigInteger(b, bigInt, offset);
        break;
      default:
        throw new IllegalArgumentException("Unsupported decimal type size: " + size);
    }
  }


  public static byte[] fromBigDecimal(final BigDecimal n, int precision) {
    int size = DecimalUtil.precisionToSize(precision);
    switch (size) {
      case  DecimalUtil.DECIMAL32_SIZE:
        return fromInt(n.unscaledValue().intValue());
      case DecimalUtil.DECIMAL64_SIZE:
        return fromLong(n.unscaledValue().longValue());
      case DecimalUtil.DECIMAL128_SIZE:
        return fromBigInteger(n.unscaledValue());
      default:
        throw new IllegalArgumentException("Unsupported decimal type size: " + size);
    }
  }


  public static byte[] UTF8(final String s) {
    return s.getBytes(CharsetUtil.UTF_8);
  }

  public static byte[] ISO88591(final String s) {
    return s.getBytes(CharsetUtil.ISO_8859_1);
  }


  private static final char[] HEX = {
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
      'A', 'B', 'C', 'D', 'E', 'F'
  };


  public static void pretty(final StringBuilder outbuf, final byte[] array) {
    if (array == null) {
      outbuf.append("null");
      return;
    }
    int ascii = 0;
    final int start_length = outbuf.length();
    final int n = array.length;
    outbuf.ensureCapacity(start_length + 1 + n + 1);
    outbuf.append('"');
    for (int i = 0; i < n; i++) {
      final byte b = array[i];
      if (' ' <= b && b <= '~') {
        ascii++;
        outbuf.append((char) b);
      } else if (b == '\n') {
        outbuf.append('\\').append('n');
      } else if (b == '\t') {
        outbuf.append('\\').append('t');
      } else {
        outbuf.append("\\x")
            .append(HEX[(b >>> 4) & 0x0F])
            .append(HEX[b & 0x0F]);
      }
    }
    if (ascii < n / 2) {
      outbuf.setLength(start_length);
      outbuf.append(Arrays.toString(array));
    } else {
      outbuf.append('"');
    }
  }


  public static void pretty(final StringBuilder outbuf, final byte[][] arrays) {
    if (arrays == null) {
      outbuf.append("null");
      return;
    } else {  // Do some right-sizing.
      int size = 2;
      for (int i = 0; i < arrays.length; i++) {
        size += 2 + 2 + arrays[i].length;
      }
      outbuf.ensureCapacity(outbuf.length() + size);
    }
    outbuf.append('[');
    for (int i = 0; i < arrays.length; i++) {
      Bytes.pretty(outbuf, arrays[i]);
      outbuf.append(", ");
    }
    outbuf.setLength(outbuf.length() - 2);  // Remove the last ", "
    outbuf.append(']');
  }


  public static String pretty(final byte[] array) {
    if (array == null) {
      return "null";
    }
    final StringBuilder buf = new StringBuilder(1 + array.length + 1);
    pretty(buf, array);
    return buf.toString();
  }


  public static String pretty(final ByteBuf buf) {
    if (buf == null) {
      return "null";
    }
    byte[] array = new byte[buf.readableBytes()];
    buf.getBytes(buf.readerIndex(), array);
    return pretty(array);
  }


  public static String hex(byte[] bytes) {
    StringBuilder sb = new StringBuilder(2 + bytes.length * 2);
    sb.append('0');
    sb.append('x');
    sb.append(BaseEncoding.base16().encode(bytes));
    return sb.toString();
  }


  public static final MemCmp MEMCMP = new MemCmp();


  private static final class MemCmp implements Comparator, Serializable {

    private static final long serialVersionUID = 914981342853419168L;

    private MemCmp() {
    }

    @Override
    public int compare(final byte[] a, final byte[] b) {
      return memcmp(a, b);
    }

  }


  public static int memcmp(final byte[] a, final byte[] b) {
    final int length = Math.min(a.length, b.length);
    if (a == b) {
      return 0;
    }
    for (int i = 0; i < length; i++) {
      if (a[i] != b[i]) {
        return (a[i] & 0xFF) - (b[i] & 0xFF);  // "promote" to unsigned.
      }
    }
    return a.length - b.length;
  }


  public static int memcmp(final byte[] a, final byte[] b,
                           final int offset, int length) {
    if (a == b && a != null) {
      return 0;
    }
    length += offset;
    for (int i = offset; i < length; i++) {
      if (a[i] != b[i]) {
        return (a[i] & 0xFF) - (b[i] & 0xFF);  // "promote" to unsigned.
      }
    }
    return 0;
  }


  public static byte[] deDup(final byte[] old, final byte[] neww) {
    return memcmp(old, neww) == 0 ? old : neww;
  }


  public static boolean equals(final byte[] a, final byte[] b) {
    return memcmp(a, b) == 0;
  }


  public static int memcmpMaybeNull(final byte[] a, final byte[] b) {
    if (a == null) {
      if (b == null) {
        return 0;
      }
      return -1;
    } else if (b == null) {
      return 1;
    }
    return memcmp(a, b);
  }

  public static int getBitSetSize(int items) {
    return (items + 7) / 8;
  }

  public static byte[] fromBitSet(BitSet bits, int colCount) {
    byte[] bytes = new byte[getBitSetSize(colCount)];
    for (int i = 0; i < Math.min(bits.length(), colCount); i++) {
      if (bits.get(i)) {
        bytes[i / 8] |= (byte)(1 << (i % 8));
      }
    }
    return bytes;
  }

  public static BitSet toBitSet(byte[] b, int offset, int colCount) {
    BitSet bs = new BitSet(colCount);
    for (int i = 0; i < colCount; i++) {
      if ((b[offset + (i / 8)] >> (i % 8) & 1) == 1) {
        bs.set(i);
      }
    }
    return bs;
  }


  public static byte xorLeftMostBit(byte value) {
    value ^= (byte)(1 << 7);
    return value;
  }


  public static byte[] fromString(String data) {
    return UTF8(data);
  }


  public static String getString(byte[] b) {
    return getString(b, 0, b.length);
  }

  public static String getString(Slice slice) {
    return slice.toString(CharsetUtil.UTF_8);
  }


  public static String getString(byte[] b, int offset, int len) {
    if (len == 0) {
      return "";
    }
    return new String(b, offset, len, CharsetUtil.UTF_8);
  }


  public static void writeByteArray(DataOutput dataOutput, byte[] b) throws IOException {
    dataOutput.writeInt(b.length);
    dataOutput.write(b);
  }

  public static byte[] readByteArray(DataInput dataInput) throws IOException {
    int len = dataInput.readInt();
    byte[] data = new byte[len];
    dataInput.readFully(data);
    return data;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy