public void offer ( float value ) { // update min/max if ( value < min ) { min = value ; } if ( value > max ) { max = value ; } // initial value if ( binCount == 0 ) { positions [ 0 ] = value ; bins [ 0 ] = 1 ; count ++ ; binCount ++ ; return ; } final int index = Arrays . binarySearch ( positions , 0 , binCount , value ) ; if ( index >= 0 ) { // we have an exact match, simply increase the count, but keep the approximate flag bins [ index ] = ( bins [ index ] & APPROX_FLAG_BIT ) | ( ( bins [ index ] & COUNT_BITS ) + 1 ) ; count ++ ; return ; } // otherwise merge the value into a new or existing bin at the following position final int insertAt = - ( index + 1 ) ; if ( binCount < size ) { // we have a spare slot, put the value into a new bin shiftRight ( insertAt , binCount ) ; positions [ insertAt ] = value ; bins [ insertAt ] = 1 ; count ++ ; binCount ++ ; return ; } // no more slots available merge the new value into and existing bin // or merge existing bins before inserting the new one int minPos = minDeltaIndex ( ) ; float minDelta = minPos >= 0 ? positions [ minPos + 1 ] - positions [ minPos ] : Float . POSITIVE_INFINITY ; // determine the distance of new value to the nearest bins final float deltaRight = insertAt < binCount ? positions [ insertAt ] - value : Float . POSITIVE_INFINITY ; final float deltaLeft = insertAt > 0 ? value - positions [ insertAt - 1 ] : Float . POSITIVE_INFINITY ; boolean mergeValue = false ; if ( deltaRight < minDelta ) { minDelta = deltaRight ; minPos = insertAt ; mergeValue = true ; } if ( deltaLeft < minDelta ) { minPos = insertAt - 1 ; mergeValue = true ; } if ( mergeValue ) { // merge new value into an existing bin and set approximate flag final long k = bins [ minPos ] & COUNT_BITS ; positions [ minPos ] = ( positions [ minPos ] * k + value ) / ( k + 1 ) ; bins [ minPos ] = ( k + 1 ) | APPROX_FLAG_BIT ; count ++ ; } else { // merge the closest bins together and insert new value as a separate bin mergeInsert ( minPos , insertAt , value , 1 ) ; } }
Adds the given value to the histogram