Search code examples
javadisruptor-pattern

Why is RingBuffer's getBufferSize() an int but remainingCapacity() is a long?


I am writing some unit test code and need to know that all events published to a disruptor's ring buffer were processed (as said, it's only for a specific test case).

After researching for a couple of hours and not finding any elegant solution I decided to use the following code in the test case:

while (ringBuffer.getBufferSize() > ringBuffer.remainingCapacity()) {
    Thread.yield();
}

It seems to work, but since getBufferSize() returns an int and remainingCapacity() returns a long I'm concerned that I'm overlooking something.

Anyone knows why getBufferSize() returns an int and remainingCapacity() returns a long? It just doesn't make sense to me, unless it's a bug.


Solution

  • Note: I don't know why the authors don't cast down to an int. However, I can tell you why it needs to be long OR a downcast is needed:

    ringBuffer.remainingCapacity is a long because it is calculated based on the bufferSize, subtracting produced and adding consumed, as seen here in MultiProducerSequencer:

    /**
     * @see Sequencer#remainingCapacity()
     */
    @Override
    public long remainingCapacity()
    {
        long consumed = Util.getMinimumSequence(gatingSequences, cursor.get());
        long produced = cursor.get();
        return getBufferSize() - (produced - consumed);
    }
    

    getBufferSize is an int. Since both consumed and produced are a long (and need to be), this resulting math will also be a long.

    This is just my educated guess, but I assume they don't downcast back to an int for performance reasons, there's no actual harm in returning a long, but it's just slightly faster to return the type you have, rather than forcing a cast on users that may not be needed.