/** * Offer two elements at the same time. * * <p>Don't use the regular offer() with this at all! * * @param first * @param second * @return */ public boolean offer(T first, T second) { final AtomicReferenceArray<Object> buffer = producerBuffer; final long p = producerIndex; final int m = producerMask; int pi = calcWrappedOffset(p + 2, m); if (null == lvElement(buffer, pi)) { pi = calcWrappedOffset(p, m); soElement(buffer, pi + 1, second); soProducerIndex(p + 2); soElement(buffer, pi, first); } else { final int capacity = buffer.length(); final AtomicReferenceArray<Object> newBuffer = new AtomicReferenceArray<>(capacity); producerBuffer = newBuffer; pi = calcWrappedOffset(p, m); soElement(newBuffer, pi + 1, second); // StoreStore soElement(newBuffer, pi, first); soNext(buffer, newBuffer); soProducerIndex(p + 2); // this ensures correctness on 32bit platforms soElement(buffer, pi, HAS_NEXT); // new buffer is visible after element is } return true; }
private void resize( final AtomicReferenceArray<Object> oldBuffer, final long currIndex, final int offset, final T e, final long mask) { final int capacity = oldBuffer.length(); final AtomicReferenceArray<Object> newBuffer = new AtomicReferenceArray<>(capacity); producerBuffer = newBuffer; producerLookAhead = currIndex + mask - 1; soProducerIndex(currIndex + 1); // this ensures correctness on 32bit platforms soElement(newBuffer, offset, e); // StoreStore soNext(oldBuffer, newBuffer); soElement(oldBuffer, offset, HAS_NEXT); // new buffer is visible after element is // inserted }
private static final <E> Object lvElement(AtomicReferenceArray<Object> buffer, int offset) { return buffer.get(offset); }
private static final void soElement(AtomicReferenceArray<Object> buffer, int offset, Object e) { buffer.lazySet(offset, e); }
@SuppressWarnings("unchecked") private AtomicReferenceArray<Object> lvNext(AtomicReferenceArray<Object> curr) { return (AtomicReferenceArray<Object>) lvElement(curr, calcDirectOffset(curr.length() - 1)); }
private void soNext(AtomicReferenceArray<Object> curr, AtomicReferenceArray<Object> next) { soElement(curr, calcDirectOffset(curr.length() - 1), next); }