@ SuppressWarnings ( "unchecked" ) public synchronized void expandExpedited ( int additionalCapacity ) { if ( additionalCapacity <= 0 ) { throw new IllegalArgumentException ( ) ; } int capacityBefore = expeditedBuffer . length ; synchronized ( lock ) { // D312598 int capacityAfter = expeditedBuffer . length ; //Check that no one was expanding while we waited on this lock if ( capacityAfter == capacityBefore ) { final Object [ ] newBuffer = new Object [ expeditedBuffer . length + additionalCapacity ] ; // PK53203 - put() acquires two locks in sequence. First, it acquires // the insert lock to update putIndex. Then, it drops the insert lock // and acquires the extract lock to update numberOfUsedSlots. As a // result, there is a window where putIndex has been updated, but // numberOfUsedSlots has not. Consequently, even though we have // acquired both locks in this method, we cannot rely on the values in // numberOfUsedSlots; we can only rely on putIndex and takeIndex. if ( expeditedPutIndex > expeditedTakeIndex ) { // The contents of the buffer do not wrap round // the end of the array. We can move its contents // into the new expanded buffer in one go. int used = expeditedPutIndex - expeditedTakeIndex ; System . arraycopy ( expeditedBuffer , expeditedTakeIndex , newBuffer , 0 , used ) ; expeditedPutIndex = used ; // PK53203.1 - If putIndex == takeIndex, then the buffer is either // completely full or completely empty. If it is completely full, then // we need to copy and adjust putIndex. Otherwise, we need to set // putIndex to 0. } else if ( expeditedPutIndex != expeditedTakeIndex || expeditedBuffer [ expeditedTakeIndex ] != null ) { // The contents of the buffer wrap round the end // of the array. We have to perform two copies to // move its contents into the new buffer. int used = expeditedBuffer . length - expeditedTakeIndex ; System . arraycopy ( expeditedBuffer , expeditedTakeIndex , newBuffer , 0 , used ) ; System . arraycopy ( expeditedBuffer , 0 , newBuffer , used , expeditedPutIndex ) ; expeditedPutIndex += used ; } else { expeditedPutIndex = 0 ; } // The contents of the buffer now begin at 0 - update the head pointer. expeditedTakeIndex = 0 ; // The buffer's capacity has been increased so update the count of the // empty slots to reflect this. expeditedBuffer = ( T [ ] ) newBuffer ; } } // D312598 }
Increases the expedited buffer s capacity by the given amount .