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

com.clickzetta.platform.util.ByteVec Maven / Gradle / Ivy

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

import com.google.common.base.Preconditions;
import com.google.common.io.BaseEncoding;
import com.google.common.primitives.Bytes;

import javax.annotation.concurrent.NotThreadSafe;
import java.util.Arrays;
import java.util.List;


@NotThreadSafe
public final class ByteVec implements Cloneable {

  /** Default initial capacity for new vectors. */

  static final int DEFAULT_CAPACITY = 32;

  /** data backing the vector. */
  private byte[] data;

  /** offset of first unused element in data. */
  private int len;

  private ByteVec(int capacity) {
    data = new byte[capacity];
    len = 0;
  }

  private ByteVec(byte[] data) {
    this.data = data;
    this.len = data.length;
  }


  public static ByteVec create() {
    return new ByteVec(DEFAULT_CAPACITY);
  }


  public static ByteVec withCapacity(int capacity) {
    return new ByteVec(capacity);
  }


  public static ByteVec wrap(byte[] data) {
    return new ByteVec(data);
  }

  /** Returns the number of elements the vector can hold without reallocating. */
  public int capacity() {
    return data.length;
  }

  /** Returns the primitive array backing the vector. The caller should not modify the array. */
  public byte[] data() {
    return data;
  }

  /** Returns the number of elements in the vector. */
  public int len() {
    return len;
  }

  /** Returns {@code true} if the vector is empty. */
  public boolean isEmpty() {
    return len == 0;
  }


  public void reserveAdditional(int additional) {
    Preconditions.checkArgument(additional >= 0, "negative additional");
    if (data.length - len >= additional) {
      return;
    }

    data = Arrays.copyOf(data, Math.max(len + additional,
                                        data.length + data.length / 2));
  }


  public void reserveExact(int additional) {
    Preconditions.checkArgument(additional >= 0, "negative additional");
    if (data.length - len >= additional) {
      return;
    }
    data = Arrays.copyOf(data, len + additional);
  }


  public void shrinkToFit() {
    if (len < data.length) {
      data = Arrays.copyOf(data, len);
    }
  }


  public void truncate(int len) {
    Preconditions.checkArgument(len >= 0, "negative len");
    this.len = Math.min(this.len, len);
  }


  public void clear() {
    truncate(0);
  }


  public void push(byte element) {
    reserveAdditional(1);
    data[len++] = element;
  }


  public void set(int index, byte value) {
    if (index >= len) {
      throw new IndexOutOfBoundsException(String.format("index: %s, len: %s", index, len));
    }
    data[index] = value;
  }


  public void append(byte[] values, int offset, int len) {
    reserveAdditional(len);
    System.arraycopy(values, offset, this.data, this.len, len);
    this.len += len;
  }


  public void append(byte[] values) {
    append(values, 0, values.length);
  }


  public void append(ByteVec other) {
    append(other.data, 0, other.len);
  }

  public byte get(int index) {
    if (index >= len) {
      throw new IndexOutOfBoundsException(String.format("index: %s, len: %s", index, len));
    }
    return data[index];
  }


  public List asList() {
    List list = Bytes.asList(data);
    if (len < data.length) {
      return list.subList(0, len);
    }
    return list;
  }

  public byte[] toArray() {
    return Arrays.copyOf(data, len);
  }


  @Override
  public String toString() {
    if (len == 0) {
      return "[]";
    }

    StringBuilder builder = new StringBuilder(4 + len * 2);
    builder.append("[0x");
    builder.append(BaseEncoding.base16().encode(data, 0, len));
    builder.append(']');
    return builder.toString();
  }


  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    ByteVec other = (ByteVec) o;
    if (len != other.len) {
      return false;
    }
    for (int i = 0; i < len; i++) {
      if (data[i] != other.data[i]) {
        return false;
      }
    }
    return true;
  }


  @Override
  public int hashCode() {
    int result = len;
    for (int i = 0; i < len; i++) {
      result = 31 * result + data[i];
    }
    return result;
  }


  @Override
  public ByteVec clone() {
    ByteVec clone = ByteVec.withCapacity(data.length);
    clone.append(this);
    return clone;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy