public static int size(IndexedQueue iq, int divisor) {
        /*
         * It is possible for a thread to be interrupted or reschedule between the reads of the producer and
         * consumer indices. It is also for the indices to be updated in a `weakly` visible way. It follows that
         * the size value needs to be sanitized to match a valid range.
         */
        long after = iq.lvConsumerIndex();
        long size;
        while (true)
        {
            final long before = after;
            // pIndex read is "sandwiched" between 2 cIndex reads
            final long currentProducerIndex = iq.lvProducerIndex();
            after = iq.lvConsumerIndex();
            if (before == after)
            {
                size = (currentProducerIndex - after) / divisor;
                break;
            }
        }
        return sanitizedSize(iq.capacity(), size);
    }
A note to maintainers on index assumptions: in a single threaded world it would seem intuitive to assume:
<pre>
<code>producerIndex >= consumerIndex</code>
</pre>
As an invariant, but in a concurrent, long running settings all of the following need to be considered:
<ul>
    <li> <code>consumerIndex > producerIndex</code> : due to counter overflow (unlikey with longs, but easy to reason)
    <li> <code>consumerIndex > producerIndex</code> : due to consumer FastFlow like implementation discovering the
    element before the counter is updated.
    <li> <code>producerIndex - consumerIndex < 0</code> : due to above.
    <li> <code>producerIndex - consumerIndex > Integer.MAX_VALUE</code> : as linked buffers allow constructing queues
    with more than <code>Integer.MAX_VALUE</code> elements.

</ul>
jctools-core/src/main/java/org/jctools/queues/IndexedQueueSizeUtil.java