private void updateIndexedRemainingUnits(
      IndexedRemainingUnits indexedRemainingUnits, long units) {
    Allocation allocation = indexedRemainingUnits.allocation;

    long newUnits = indexedRemainingUnits.remainingUnits.addAndGet(-units);
    if (newUnits < 0L) {
      throw new IllegalStateException(
          "Progress exceeds max for '"
              + allocation.getDescription()
              + "': "
              + -newUnits
              + " more beyond "
              + allocation.getAllocationUnits());
    }

    // Updates the parent allocations if this allocation completed.
    if (newUnits == 0L) {
      allocation
          .getParent()
          .ifPresent(
              parentAllocation ->
                  updateIndexedRemainingUnits(
                      Preconditions.checkNotNull(completionMap.get(parentAllocation)), 1L));
    }
  }
Helper method for {@link #updateProgress(Allocation, long)}. Subtract {@code units} from {@code
indexedRemainingUnits}. Updates {@link IndexedRemainingUnits} for parent {@link Allocation}s if
remaining units becomes 0. This method is <em>not</em> thread-safe for the {@code
indexedRemainingUnits} and should be called atomically relative to the {@code
indexedRemainingUnits}.

@param indexedRemainingUnits the {@link IndexedRemainingUnits} to update progress for
@param units the units of progress
jib-core/src/main/java/com/google/cloud/tools/jib/event/progress/AllocationCompletionTracker.java