/** * Return {@code true} if direct memory cache alignment is supported, {@code false} otherwise. */ public static boolean isDirectMemoryCacheAlignmentSupported() { return PlatformDependent.hasUnsafe(); }
/** * Create new instance * * @param preferDirect {@code true} if {@link #buffer(int)} should try to allocate a direct buffer rather than * a heap buffer */ protected AbstractByteBufAllocator(boolean preferDirect) { directByDefault = preferDirect && PlatformDependent.hasUnsafe(); emptyBuf = new EmptyByteBuf(this); }
private static long byteArrayBaseOffset0() { if (!hasUnsafe()) { return -1; } return PlatformDependent0.byteArrayBaseOffset(); }
private static int addressSize0() { if (!hasUnsafe()) { return -1; } return PlatformDependent0.addressSize(); }
public byte byteAt(int index) { // We must do a range check here to enforce the access does not go outside our sub region of the array. // We rely on the array access itself to pick up the array out of bounds conditions if (index < 0 || index >= length) { throw new IndexOutOfBoundsException("index: " + index + " must be in the range [0," + length + ")"); } // Try to use unsafe to avoid double checking the index bounds if (PlatformDependent.hasUnsafe()) { return PlatformDependent.getByte(value, index + offset); } return value[index + offset]; }
private int getInt(int index, int offset) { if (PlatformDependent.hasUnsafe()) { return PlatformDependent.getInt(memoryAddress + index * EPOLL_EVENT_SIZE + offset); } return memory.getInt(index * EPOLL_EVENT_SIZE + offset); }
/** * Raises an exception bypassing compiler checks for checked exceptions. */ public static void throwException(Throwable t) { if (hasUnsafe()) { PlatformDependent0.throwException(t); } else { PlatformDependent.<RuntimeException>throwException0(t); } }
@Override public ByteBuf ioBuffer() { if (PlatformDependent.hasUnsafe()) { return directBuffer(DEFAULT_INITIAL_CAPACITY); } return heapBuffer(DEFAULT_INITIAL_CAPACITY); }
@Override protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) { return PlatformDependent.hasUnsafe() ? new InstrumentedUnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity) : new InstrumentedUnpooledHeapByteBuf(this, initialCapacity, maxCapacity); }
@Override public ByteBuf ioBuffer(int initialCapacity, int maxCapacity) { if (PlatformDependent.hasUnsafe()) { return directBuffer(initialCapacity, maxCapacity); } return heapBuffer(initialCapacity, maxCapacity); }
/** * Create a new {@link Queue} which is safe to use for single producer (one thread!) and a single * consumer (one thread!). */ public static <T> Queue<T> newSpscQueue() { return hasUnsafe() ? new SpscLinkedQueue<T>() : new SpscLinkedAtomicQueue<T>(); }
/** * Create a new {@link Queue} which is safe to use for multiple producers (different threads) and a single * consumer (one thread!) with the given fixes {@code capacity}. */ public static <T> Queue<T> newFixedMpscQueue(int capacity) { return hasUnsafe() ? new MpscArrayQueue<T>(capacity) : new MpscAtomicArrayQueue<T>(capacity); }
@Override public ByteBuf ioBuffer(int initialCapacity) { if (PlatformDependent.hasUnsafe()) { return directBuffer(initialCapacity); } return heapBuffer(initialCapacity); }
/** * Returns a cached thread-local direct buffer, if available. * * @return a cached thread-local direct buffer, if available. {@code null} otherwise. */ public static ByteBuf threadLocalDirectBuffer() { if (THREAD_LOCAL_BUFFER_SIZE <= 0) { return null; } if (PlatformDependent.hasUnsafe()) { return ThreadLocalUnsafeDirectByteBuf.newInstance(); } else { return ThreadLocalDirectByteBuf.newInstance(); } }
/** * Determine if a subsection of an array is zero. * @param bytes The byte array. * @param startPos The starting index (inclusive) in {@code bytes}. * @param length The amount of bytes to check for zero. * @return {@code false} if {@code bytes[startPos:startsPos+length)} contains a value other than zero. */ public static boolean isZero(byte[] bytes, int startPos, int length) { return !hasUnsafe() || !unalignedAccess() ? isZeroSafe(bytes, startPos, length) : PlatformDependent0.isZero(bytes, startPos, length); }
/** * Calculate a hash code of a byte array assuming ASCII character encoding. * The resulting hash code will be case insensitive. * @param bytes The array which contains the data to hash. * @param startPos What index to start generating a hash code in {@code bytes} * @param length The amount of bytes that should be accounted for in the computation. * @return The hash code of {@code bytes} assuming ASCII character encoding. * The resulting hash code will be case insensitive. */ public static int hashCodeAscii(byte[] bytes, int startPos, int length) { return !hasUnsafe() || !unalignedAccess() ? hashCodeAsciiSafe(bytes, startPos, length) : PlatformDependent0.hashCodeAscii(bytes, startPos, length); }
/** * Compare two {@code byte} arrays for equality. For performance reasons no bounds checking on the * parameters is performed. * * @param bytes1 the first byte array. * @param startPos1 the position (inclusive) to start comparing in {@code bytes1}. * @param bytes2 the second byte array. * @param startPos2 the position (inclusive) to start comparing in {@code bytes2}. * @param length the amount of bytes to compare. This is assumed to be validated as not going out of bounds * by the caller. */ public static boolean equals(byte[] bytes1, int startPos1, byte[] bytes2, int startPos2, int length) { return !hasUnsafe() || !unalignedAccess() ? equalsSafe(bytes1, startPos1, bytes2, startPos2, length) : PlatformDependent0.equals(bytes1, startPos1, bytes2, startPos2, length); }
@Override protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { final ByteBuf buf; if (PlatformDependent.hasUnsafe()) { buf = noCleaner ? new InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf(this, initialCapacity, maxCapacity) : new InstrumentedUnpooledUnsafeDirectByteBuf(this, initialCapacity, maxCapacity); } else { buf = new InstrumentedUnpooledDirectByteBuf(this, initialCapacity, maxCapacity); } return disableLeakDetector ? buf : toLeakAwareBuffer(buf); }
@Override protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) { PoolThreadCache cache = threadCache.get(); PoolArena<byte[]> heapArena = cache.heapArena; final ByteBuf buf; if (heapArena != null) { buf = heapArena.allocate(cache, initialCapacity, maxCapacity); } else { buf = PlatformDependent.hasUnsafe() ? new UnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity) : new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity); } return toLeakAwareBuffer(buf); }
@Override protected ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity) { PoolThreadCache cache = threadCache.get(); PoolArena<ByteBuffer> directArena = cache.directArena; final ByteBuf buf; if (directArena != null) { buf = directArena.allocate(cache, initialCapacity, maxCapacity); } else { buf = PlatformDependent.hasUnsafe() ? UnsafeByteBufUtil.newUnsafeDirectByteBuf(this, initialCapacity, maxCapacity) : new UnpooledDirectByteBuf(this, initialCapacity, maxCapacity); } return toLeakAwareBuffer(buf); }