InMemoryReservationAllocation(ReservationId reservationID, ReservationDefinition contract, String user, String planName, long startTime, long endTime, Map<ReservationInterval, ReservationRequest> allocationRequests, ResourceCalculator calculator, Resource minAlloc) { this.contract = contract; this.startTime = startTime; this.endTime = endTime; this.reservationID = reservationID; this.user = user; this.allocationRequests = allocationRequests; this.planName = planName; resourcesOverTime = new RLESparseResourceAllocation(calculator, minAlloc); for (Map.Entry<ReservationInterval, ReservationRequest> r : allocationRequests .entrySet()) { resourcesOverTime.addInterval(r.getKey(), r.getValue()); if (r.getValue().getConcurrency() > 1) { hasGang = true; } } }
/** * Get capacity at time based on periodic repetition. * * @param tick UTC time for which the allocated {@link Resource} is queried. * @return {@link Resource} allocated at specified time */ public Resource getCapacityAtTime(long tick) { long convertedTime = (tick % timePeriod); return super.getCapacityAtTime(convertedTime); }
private void decrementAllocation(ReservationAllocation reservation) { assert (readWriteLock.isWriteLockedByCurrentThread()); Map<ReservationInterval, ReservationRequest> allocationRequests = reservation.getAllocationRequests(); String user = reservation.getUser(); RLESparseResourceAllocation resAlloc = userResourceAlloc.get(user); for (Map.Entry<ReservationInterval, ReservationRequest> r : allocationRequests .entrySet()) { resAlloc.removeInterval(r.getKey(), r.getValue()); rleSparseVector.removeInterval(r.getKey(), r.getValue()); } if (resAlloc.isEmpty()) { userResourceAlloc.remove(user); } }
/** * Get maximum capacity at periodic offsets from the specified time. * * @param tick UTC time base from which offsets are specified for finding the * maximum capacity. * @param period periodic offset at which capacities are evaluated. * @return the maximum {@link Resource} across the specified time instants. * @return true if removal is successful, false otherwise */ public Resource getMaximumPeriodicCapacity(long tick, long period) { Resource maxResource; if (period < timePeriod) { maxResource = super.getMaximumPeriodicCapacity(tick % timePeriod, period); } else { // if period is greater than the length of PeriodicRLESparseAllocation, // only a single value exists in this interval. maxResource = super.getCapacityAtTime(tick % timePeriod); } return maxResource; }
/** * Merges the range start to end of two {@code RLESparseResourceAllocation} * using a given {@code RLEOperator}. * * @param resCalc the resource calculator * @param clusterResource the total cluster resources (for DRF) * @param a the left operand * @param b the right operand * @param operator the operator to be applied during merge * @param start the start-time of the range to be considered * @param end the end-time of the range to be considered * @return the a merged RLESparseResourceAllocation, produced by applying * "operator" to "a" and "b" * @throws PlanningException in case the operator is subtractTestPositive and * the result would contain a negative value */ public static RLESparseResourceAllocation merge(ResourceCalculator resCalc, Resource clusterResource, RLESparseResourceAllocation a, RLESparseResourceAllocation b, RLEOperator operator, long start, long end) throws PlanningException { NavigableMap<Long, Resource> cumA = a.getRangeOverlapping(start, end).getCumulative(); NavigableMap<Long, Resource> cumB = b.getRangeOverlapping(start, end).getCumulative(); NavigableMap<Long, Resource> out = merge(resCalc, clusterResource, cumA, cumB, start, end, operator); return new RLESparseResourceAllocation(out, resCalc); }
@Test public void testZeroAllocation() { ResourceCalculator resCalc = new DefaultResourceCalculator(); RLESparseResourceAllocation rleSparseVector = new RLESparseResourceAllocation(resCalc); rleSparseVector.addInterval(new ReservationInterval(0, Long.MAX_VALUE), Resource.newInstance(0, 0)); LOG.info(rleSparseVector.toString()); Assert.assertEquals(Resource.newInstance(0, 0), rleSparseVector.getCapacityAtTime(new Random().nextLong())); Assert.assertTrue(rleSparseVector.isEmpty()); }
plan.getTotalCommittedResources(t)); Resources.subtractFrom(netAvailableRes, tempAssigned.getCapacityAtTime(t)); tempAssigned.addInterval(reservationInt, reservationRes); allocationRequests.put(reservationInt, reservationRes); tempAssigned.removeInterval(tempAllocation.getKey(), tempAllocation.getValue());
@Test public void testRangeOverlapping() { ResourceCalculator resCalc = new DefaultResourceCalculator(); RLESparseResourceAllocation r = new RLESparseResourceAllocation(resCalc); int[] alloc = { 10, 10, 10, 10, 10, 10 }; int start = 100; Set<Entry<ReservationInterval, Resource>> inputs = generateAllocation(start, alloc, false).entrySet(); for (Entry<ReservationInterval, Resource> ip : inputs) { r.addInterval(ip.getKey(), ip.getValue()); } long s = r.getEarliestStartTime(); long d = r.getLatestNonNullTime(); // tries to trigger "out-of-range" bug r = r.getRangeOverlapping(s, d); r = r.getRangeOverlapping(s - 1, d - 1); r = r.getRangeOverlapping(s + 1, d + 1); }
new RLESparseResourceAllocation(instQuota, plan.getResourceCalculator()); used = RLESparseResourceAllocation.merge(plan.getResourceCalculator(), Resources.clone(plan.getTotalCapacity()), used, old.getResourcesOverTime(start, end), RLEOperator.subtract, start, .merge(plan.getResourceCalculator(), planTotalCapacity, instRLEQuota, used, RLEOperator.subtract, start, end); .merge(plan.getResourceCalculator(), planTotalCapacity, available, instRLEQuota, RLEOperator.min, start, end);
new RLESparseResourceAllocation(plan.getResourceCalculator()); rr.getConcurrency() * numGangsToAllocate); planModifications.addInterval(reservationInt, reservationRes); allocationRequests.addInterval(reservationInt, reservationRes); allocationRequests.toIntervalMap(); .entrySet()) { planModifications.removeInterval(tempAllocation.getKey(), tempAllocation.getValue());
RLESparseResourceAllocation.merge(plan.getResourceCalculator(), plan.getTotalCapacity(), netAvailable, planModifications, RLEOperator.subtract, stageEarliestStart, stageDeadline); && maxGang > 0; t = t - plan.getStep()) { Resource netAvailableRes = netAvailable.getCapacityAtTime(t); planModifications.addInterval(reservationInt, reservationRes); allocationRequests.put(reservationInt, reservationRes); planModifications.removeInterval(tempAllocation.getKey(), tempAllocation.getValue());
new RLESparseResourceAllocation(plan.getResourceCalculator()); allocations.addInterval(entry.getKey(), entry.getValue()); if (allocations.isEmpty()) { throw new PlanningException("The request cannot be satisfied");
if (old != null) { consumptionForUserOverTime = RLESparseResourceAllocation.merge(plan.getResourceCalculator(), plan.getTotalCapacity(), consumptionForUserOverTime, old.getResourcesOverTime(checkStart, checkEnd), RLEOperator.add, .merge(plan.getResourceCalculator(), plan.getTotalCapacity(), consumptionForUserOverTime, resRLE, RLEOperator.add, Long.MIN_VALUE, Long.MAX_VALUE); long prevTime = toCheck.getEarliestStartTime(); IntegralResource prevResource = new IntegralResource(0L, 0L); IntegralResource runningTot = new IntegralResource(0L, 0L); for (Map.Entry<Long, Resource> pointToCheck : toCheck.getCumulative() .entrySet()) { Long nextPoint = toCheck.getCumulative().higherKey(timeToCheck); if (nextPoint == null || toCheck.getCumulative().get(nextPoint) == null) { continue; temp.putAll(toCheck.getCumulative()); new RLESparseResourceAllocation(integralUp, plan.getResourceCalculator()); RLESparseResourceAllocation intDown = new RLESparseResourceAllocation(integralDown, plan.getResourceCalculator());
ResourceCalculator resCalc = new DefaultResourceCalculator(); RLESparseResourceAllocation rleSparseVector = new RLESparseResourceAllocation(resCalc); Map<ReservationInterval, Resource> mapAllocations; mapAllocations = rleSparseVector.toIntervalMap(); Assert.assertTrue(mapAllocations.isEmpty()); generateAllocation(start, alloc, false).entrySet(); for (Entry<ReservationInterval, Resource> ip : inputs) { rleSparseVector.addInterval(ip.getKey(), ip.getValue()); mapAllocations = rleSparseVector.toIntervalMap(); Assert.assertTrue(mapAllocations.size() == 5); for (Entry<ReservationInterval, Resource> entry : mapAllocations
public String toCumulativeString() { readLock.lock(); try { return rleSparseVector.toString(); } finally { readLock.unlock(); } }
InMemoryPlan(QueueMetrics queueMetrics, SharingPolicy policy, ReservationAgent agent, Resource totalCapacity, long step, ResourceCalculator resCalc, Resource minAlloc, Resource maxAlloc, String queueName, Planner replanner, boolean getMoveOnExpiry, Clock clock) { this.queueMetrics = queueMetrics; this.policy = policy; this.agent = agent; this.step = step; this.totalCapacity = totalCapacity; this.resCalc = resCalc; this.minAlloc = minAlloc; this.maxAlloc = maxAlloc; this.rleSparseVector = new RLESparseResourceAllocation(resCalc, minAlloc); this.queueName = queueName; this.replanner = replanner; this.getMoveOnExpiry = getMoveOnExpiry; this.clock = clock; }
RLESparseResourceAllocation.merge(plan.getResourceCalculator(), totalCapacity, netRLERes, planModifications, RLEOperator.subtract, stageEarliestStart, stageDeadline); netRLERes.getRangeOverlapping(stageEarliestStart, stageDeadline) .getCumulative(); planModifications.removeInterval(tempAllocation.getKey(), tempAllocation.getValue());
@Override public RLESparseResourceAllocation getConsumptionForUserOverTime(String user, long start, long end) { readLock.lock(); try { // merge periodic and non-periodic allocations RLESparseResourceAllocation userResAlloc = userResourceAlloc.get(user); RLESparseResourceAllocation userPeriodicResAlloc = userPeriodicResourceAlloc.get(user); if (userResAlloc != null && userPeriodicResAlloc != null) { return RLESparseResourceAllocation.merge(resCalc, totalCapacity, userResAlloc, userPeriodicResAlloc, RLEOperator.add, start, end); } if (userResAlloc != null) { return userResAlloc.getRangeOverlapping(start, end); } if (userPeriodicResAlloc != null) { return userPeriodicResAlloc.getRangeOverlapping(start, end); } } catch (PlanningException e) { LOG.warn("Exception while trying to merge periodic" + " and non-periodic user allocations: {}", e.getMessage(), e); } finally { readLock.unlock(); } return new RLESparseResourceAllocation(resCalc); }
protected static boolean validateOrderNoGap( RLESparseResourceAllocation allocations, Map<ReservationInterval, Resource> curAlloc, boolean allocateLeft) { // Left to right if (allocateLeft) { Long stageStartTime = findEarliestTime(curAlloc); Long allocationEndTime = allocations.getLatestNonNullTime(); // Check that there is no gap between stages if ((allocationEndTime != -1) && (allocationEndTime < stageStartTime)) { return false; } // Right to left } else { Long stageEndTime = findLatestTime(curAlloc); Long allocationStartTime = allocations.getEarliestStartTime(); // Check that there is no gap between stages if ((allocationStartTime != -1) && (stageEndTime < allocationStartTime)) { return false; } } // Check that the stage allocation does not violate ORDER_NO_GAP if (!isNonPreemptiveAllocation(curAlloc)) { return false; } // The allocation is legal return true; }