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

com.clickzetta.platform.catalyst.memory.MemoryUtils Maven / Gradle / Ivy

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

import com.google.common.base.Preconditions;

import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class MemoryUtils {

  public static final sun.misc.Unsafe UNSAFE = getUnsafe();
  public static final ByteOrder NATIVE_BYTE_ORDER = ByteOrder.nativeOrder();
  public static final long BUFFER_ADDRESS_FIELD_OFFSET = getClassFieldOffset(Buffer.class, "address");

  private static sun.misc.Unsafe getUnsafe() {
    try {
      Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
      unsafeField.setAccessible(true);
      return (sun.misc.Unsafe) unsafeField.get(null);
    } catch (SecurityException e) {
      throw new Error(
          "Could not access the sun.misc.Unsafe handle, permission denied by security manager.",
          e);
    } catch (NoSuchFieldException e) {
      throw new Error("The static handle field in sun.misc.Unsafe was not found.", e);
    } catch (IllegalArgumentException e) {
      throw new Error("Bug: Illegal argument reflection access for static field.", e);
    } catch (IllegalAccessException e) {
      throw new Error("Access to sun.misc.Unsafe is forbidden by the runtime.", e);
    } catch (Throwable t) {
      throw new Error(
          "Unclassified error while trying to access the sun.misc.Unsafe handle.", t);
    }
  }

  private static long getClassFieldOffset(Class cl, String fieldName) {
    try {
      return UNSAFE.objectFieldOffset(cl.getDeclaredField(fieldName));
    } catch (SecurityException e) {
      throw new Error(getClassFieldOffsetErrorMessage(cl, fieldName)
          + ", permission denied by security manager.", e);
    } catch (NoSuchFieldException e) {
      throw new Error(getClassFieldOffsetErrorMessage(cl, fieldName), e);
    } catch (Throwable t) {
      throw new Error(getClassFieldOffsetErrorMessage(cl, fieldName) + ", unclassified error", t);
    }
  }

  private static String getClassFieldOffsetErrorMessage(Class cl, String fieldName) {
    String errMsg = String.format("Could not get field '%s' offset in class '%s' for unsafe operations",
        fieldName, cl);
    return errMsg;
  }

  static long getByteBufferAddress(ByteBuffer buffer) {
    Preconditions.checkNotNull(buffer, "buffer is null");
    Preconditions.checkArgument(
        buffer.isDirect(), "Can't get address of a non-direct ByteBuffer.");

    long offHeapAddress;
    try {
      offHeapAddress = UNSAFE.getLong(buffer, BUFFER_ADDRESS_FIELD_OFFSET);
    } catch (Throwable t) {
      throw new Error("Could not access direct byte buffer address field.", t);
    }

    Preconditions.checkState(offHeapAddress > 0, "negative pointer or size");
    Preconditions.checkState(
        offHeapAddress < Long.MAX_VALUE - Integer.MAX_VALUE,
        "Segment initialized with too large address: "
            + offHeapAddress
            + " ; Max allowed address is "
            + (Long.MAX_VALUE - Integer.MAX_VALUE - 1));

    return offHeapAddress;
  }

  private MemoryUtils() {
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy