Skip to content

Instantly share code, notes, and snippets.

@nitsanw
Created October 21, 2016 19:27
Show Gist options
  • Save nitsanw/840c50bfe0d01408a49b5a100cb5c7a7 to your computer and use it in GitHub Desktop.
Save nitsanw/840c50bfe0d01408a49b5a100cb5c7a7 to your computer and use it in GitHub Desktop.
@Override
protected final boolean offerColdPath(E[] buffer, long mask, E e, long pIndex, long offset) {
// use a fixed lookahead step based on buffer capacity
final long lookAheadStep = (mask + 1) / 4;
long pBufferLimit = pIndex + lookAheadStep;
long pQueueLimit = producerQueueLimit;
// out of known space
if (pIndex >= pQueueLimit) {
// we tested against a potentially out of date queue limit, refresh it
long cIndex = lvConsumerIndex();
producerQueueLimit = pQueueLimit = cIndex + maxQueueCapacity;
// if we're full we're full
if (pIndex >= pQueueLimit) {
return false;
}
}
// if buffer limit is after queue limit we use queue limit. We need to handle overflow so
// cannot use Math.min
if (pBufferLimit - pQueueLimit > 0) {
pBufferLimit = pQueueLimit;
}
// go around the buffer or add a new buffer
if (pBufferLimit > pIndex + 1 && // there's sufficient room in buffer/queue to use pBufferLimit
null == lvElement(buffer, calcElementOffset(pBufferLimit, mask))) {
producerBufferLimit = pBufferLimit - 1; // joy, there's plenty of room
writeToQueue(buffer, e, pIndex, offset);
}
else if (null == lvElement(buffer, calcElementOffset(pIndex + 1, mask))) { // buffer is not full
writeToQueue(buffer, e, pIndex, offset);
}
else {
// we got one slot left to write into, and we are not full. Need to link new buffer.
// allocate new buffer of same length
final E[] newBuffer = allocate((int)(mask + 2));
producerBuffer = newBuffer;
linkOldToNew(pIndex, buffer, offset, newBuffer, offset, e);
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment