private AllocationOutcome allocate(final long size,final boolean incomingUpdatePeak,final boolean forceAllocation){
  final long newLocal=locallyHeldMemory.addAndGet(size);
  final long beyondReservation=newLocal - reservation;
  final boolean beyondLimit=newLocal > allocationLimit.get();
  final boolean updatePeak=forceAllocation || (incomingUpdatePeak && !beyondLimit);
  AllocationOutcome parentOutcome=AllocationOutcome.SUCCESS;
  if (beyondReservation > 0 && parent != null) {
    final long parentRequest=Math.min(beyondReservation,size);
    parentOutcome=parent.allocate(parentRequest,updatePeak,forceAllocation);
  }
  final AllocationOutcome finalOutcome=beyondLimit ? AllocationOutcome.FAILED_LOCAL : parentOutcome.ok ? AllocationOutcome.SUCCESS : AllocationOutcome.FAILED_PARENT;
  if (updatePeak) {
    updatePeak();
  }
  return finalOutcome;
}

private AllocationOutcome allocate ( final long size , final boolean incomingUpdatePeak , final boolean forceAllocation ) { final long newLocal = locallyHeldMemory . addAndGet ( size ) ; final long beyondReservation = newLocal - reservation ; final boolean beyondLimit = newLocal > allocationLimit . get ( ) ; final boolean updatePeak = forceAllocation || ( incomingUpdatePeak && ! beyondLimit ) ; AllocationOutcome parentOutcome = AllocationOutcome . SUCCESS ; if ( beyondReservation > 0 && parent != null ) { final long parentRequest = Math . min ( beyondReservation , size ) ; parentOutcome = parent . allocate ( parentRequest , updatePeak , forceAllocation ) ; } final AllocationOutcome finalOutcome = beyondLimit ? AllocationOutcome . FAILED_LOCAL : parentOutcome . ok ? AllocationOutcome . SUCCESS : AllocationOutcome . FAILED_PARENT ; if ( updatePeak ) { updatePeak ( ) ; } return finalOutcome ; }
internal method for allocation . this takes a forced approach to allocation to ensure that we manage reservation boundary issues consistently . allocation is always done through the entire tree . the two options that we influence are whether the allocation should be forced and whether or not the peak memory allocation should be updated . if at some point during allocation escalation we determine that the allocation is no longer possible , we will continue to do a complete and consistent allocation but we will stop updating the peak allocation . we do this because we know that we will be directly unwinding this allocation ( and thus never actually making the allocation ) . if force allocation is passed , then we continue to update the peak limits since we now know that this allocation will occur despite our moving past one or more limits .
