Skip to content

Instantly share code, notes, and snippets.

@nitsanw
Last active October 21, 2016 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitsanw/45be60f4e051e4c2d3fecfe36a765726 to your computer and use it in GitHub Desktop.
Save nitsanw/45be60f4e051e4c2d3fecfe36a765726 to your computer and use it in GitHub Desktop.
Hot path SPSC LAQ
@Override
public boolean offer(final E e) {
Objects.requireNonNull(e);
// local load of fields to avoid repeated loads after volatile reads
final E[] buffer = producerBuffer;
final long index = producerIndex;
final long mask = producerMask;
final long offset = calcElementOffset(index, mask);
// expected hot path
if (index < producerBufferLimit) {
writeToQueue(buffer, e, index, offset);
return true;
}
return offerColdPath(buffer, mask, e, index, offset);
}
protected final void writeToQueue(final E[] buffer, final E e, final long index, final long offset) {
soElement(buffer, offset, e); // ordered: buffer[index&mask] = e;
soProducerIndex(index + 1); // ordered: producerIndex = index + 1;
}
@Override
public E poll() {
// local load of fields to avoid repeated loads after volatile reads
final E[] buffer = consumerBuffer;
final long index = consumerIndex;
final long mask = consumerMask;
final long offset = calcElementOffset(index, mask);
final Object e = lvElement(buffer, offset); // volatile: e = buffer[index&mask];
final boolean jumpToNextBuffer = (e == JUMP);
if (null != e && !jumpToNextBuffer) {
soConsumerIndex(index + 1); // ordered: consumerIndex = index + 1;
soElement(buffer, offset, null); // oredered: buffer[index&mask] = null;
return (E) e;
}
else if (jumpToNextBuffer) {
return newBufferPoll(buffer, index);
}
return null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment