public boolean offer(final E e) { if (null == e) { throw new NullPointerException("element cannot be null"); } long currentTail; long currentHead = sharedHeadCache; long bufferLimit = currentHead + capacity; do { currentTail = tail; if (currentTail >= bufferLimit) { currentHead = head; bufferLimit = currentHead + capacity; if (currentTail >= bufferLimit) { return false; } UNSAFE.putOrderedLong(this, SHARED_HEAD_CACHE_OFFSET, currentHead); } } while (!UNSAFE.compareAndSwapLong(this, TAIL_OFFSET, currentTail, currentTail + 1)); UNSAFE.putOrderedObject(buffer, sequenceToBufferOffset(currentTail, mask), e); return true; }
@SuppressWarnings("unchecked") public int drainTo(final Collection<? super E> target, final int limit) { final Object[] buffer = this.buffer; final long mask = this.mask; long nextSequence = head; int count = 0; while (count < limit) { final long elementOffset = sequenceToBufferOffset(nextSequence, mask); final Object e = UNSAFE.getObjectVolatile(buffer, elementOffset); if (null == e) { break; } UNSAFE.putOrderedObject(buffer, elementOffset, null); nextSequence++; UNSAFE.putOrderedLong(this, HEAD_OFFSET, nextSequence); count++; target.add((E) e); } return count; }
@SuppressWarnings("unchecked") public int drain(final Consumer<E> elementHandler) { final Object[] buffer = this.buffer; final long mask = this.mask; final long currentHead = head; long nextSequence = currentHead; final long limit = nextSequence + mask + 1; while (nextSequence < limit) { final long elementOffset = sequenceToBufferOffset(nextSequence, mask); final Object item = UNSAFE.getObjectVolatile(buffer, elementOffset); if (null == item) { break; } UNSAFE.putOrderedObject(buffer, elementOffset, null); nextSequence++; UNSAFE.putOrderedLong(this, HEAD_OFFSET, nextSequence); elementHandler.accept((E) item); } return (int) (nextSequence - currentHead); }
void lazySetNext(Node<E> val) { UNSAFE.putOrderedObject(this, nextOffset, val); }
protected final void soElement(E[] buffer, long offset, Object e) { UNSAFE.putOrderedObject(buffer, offset, e); }