@Override public RLESparseResourceAllocation getCumulativeLoadOverTime(long start, long end) throws PlanningException { readLock.lock(); try { RLESparseResourceAllocation ret = rleSparseVector.getRangeOverlapping(start, end); ret = RLESparseResourceAllocation.merge(resCalc, totalCapacity, ret, periodicRle.getRangeOverlapping(start, end), RLEOperator.add, start, end); return ret; } finally { readLock.unlock(); } } }
/** * Add a resource for the specified interval. * * @param reservationInterval the interval for which the resource is to be * added * @param totCap the resource to be added * @return true if addition is successful, false otherwise */ public boolean addInterval(ReservationInterval reservationInterval, Resource totCap) { if (totCap.equals(ZERO_RESOURCE)) { return true; } writeLock.lock(); try { NavigableMap<Long, Resource> addInt = new TreeMap<Long, Resource>(); addInt.put(reservationInterval.getStartTime(), totCap); addInt.put(reservationInterval.getEndTime(), ZERO_RESOURCE); try { cumulativeCapacity = merge(resourceCalculator, totCap, cumulativeCapacity, addInt, Long.MIN_VALUE, Long.MAX_VALUE, RLEOperator.add); } catch (PlanningException e) { // never happens for add } return true; } finally { writeLock.unlock(); } }
/** * Removes a resource for the specified interval. * * @param reservationInterval the interval for which the resource is to be * removed * @param totCap the resource to be removed * @return true if removal is successful, false otherwise */ public boolean removeInterval(ReservationInterval reservationInterval, Resource totCap) { if (totCap.equals(ZERO_RESOURCE)) { return true; } writeLock.lock(); try { NavigableMap<Long, Resource> removeInt = new TreeMap<Long, Resource>(); removeInt.put(reservationInterval.getStartTime(), totCap); removeInt.put(reservationInterval.getEndTime(), ZERO_RESOURCE); try { cumulativeCapacity = merge(resourceCalculator, totCap, cumulativeCapacity, removeInt, Long.MIN_VALUE, Long.MAX_VALUE, RLEOperator.subtract); } catch (PlanningException e) { // never happens for subtract } return true; } finally { writeLock.unlock(); } }
RLESparseResourceAllocation.merge(resCalc, capacity, netRLERes, planModifications, RLEOperator.subtractTestNonNegative, startTime, endTime);
@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); }
RLESparseResourceAllocation.merge(resCalc, capacity, planLoads, planModifications, RLEOperator.add, startTime, endTime);
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);
netAvailable = RLESparseResourceAllocation.merge(resCalc, Resources.clone(totalCapacity), totRLEAvail, rleSparseVector, RLEOperator.subtractTestNonNegative, start, end); netAvailable = RLESparseResourceAllocation.merge(resCalc, Resources.clone(totalCapacity), netAvailable, periodicRle, RLEOperator.subtractTestNonNegative, start, end); netAvailable = RLESparseResourceAllocation.merge(resCalc, Resources.clone(totalCapacity), netAvailable, addBackPrevious, RLEOperator.add, start, end); RLESparseResourceAllocation.merge(resCalc, getTotalCapacity(), minOverLCM, snapShot, RLEOperator.min, start, end);
/** * 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 @Ignore public void testMergeSpeed() throws PlanningException { for (int j = 0; j < 100; j++) { TreeMap<Long, Resource> a = new TreeMap<>(); TreeMap<Long, Resource> b = new TreeMap<>(); Random rand = new Random(); long startA = 0; long startB = 0; for (int i = 0; i < 1000 + rand.nextInt(9000); i++) { startA += rand.nextInt(100); startB += rand.nextInt(100); a.put(startA, Resource.newInstance(rand.nextInt(10240), rand.nextInt(10))); b.put(startB, Resource.newInstance(rand.nextInt(10240), rand.nextInt(10))); } RLESparseResourceAllocation rleA = new RLESparseResourceAllocation(a, new DefaultResourceCalculator()); RLESparseResourceAllocation rleB = new RLESparseResourceAllocation(b, new DefaultResourceCalculator()); long start = System.currentTimeMillis(); RLESparseResourceAllocation out = RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.add, Long.MIN_VALUE, Long.MAX_VALUE); long end = System.currentTimeMillis(); System.out.println(" Took: " + (end - start) + "ms "); } }
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); .merge(plan.getResourceCalculator(), plan.getTotalCapacity(), intUp, intDown, RLEOperator.subtract, Long.MIN_VALUE, Long.MAX_VALUE); RLESparseResourceAllocation.merge(plan.getResourceCalculator(), plan.getTotalCapacity(), targetLimit, integral, RLEOperator.subtractTestNonNegative, checkStart, checkEnd);
RLESparseResourceAllocation.merge(plan.getResourceCalculator(), plan.getTotalCapacity(), netAvailable, planModifications, RLEOperator.subtract, stageEarliestStart, stageDeadline);
@Test public void testMergeAdd() throws PlanningException { TreeMap<Long, Resource> a = new TreeMap<>(); TreeMap<Long, Resource> b = new TreeMap<>(); setupArrays(a, b); RLESparseResourceAllocation rleA = new RLESparseResourceAllocation(a, new DefaultResourceCalculator()); RLESparseResourceAllocation rleB = new RLESparseResourceAllocation(b, new DefaultResourceCalculator()); RLESparseResourceAllocation out = RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.add, 18, 45); System.out.println(out); long[] time = { 18, 20, 22, 30, 33, 40, 43, 45 }; int[] alloc = { 10, 15, 20, 25, 30, 40, 30 }; validate(out, time, alloc); }
@Test public void testMergeMin() throws PlanningException { TreeMap<Long, Resource> a = new TreeMap<>(); TreeMap<Long, Resource> b = new TreeMap<>(); setupArrays(a, b); RLESparseResourceAllocation rleA = new RLESparseResourceAllocation(a, new DefaultResourceCalculator()); RLESparseResourceAllocation rleB = new RLESparseResourceAllocation(b, new DefaultResourceCalculator()); RLESparseResourceAllocation out = RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.min, 0, 60); System.out.println(out); long[] time = { 10, 22, 33, 40, 43, 50, 60 }; int[] alloc = { 5, 10, 15, 20, 10, 0 }; validate(out, time, alloc); }
@Test public void testMergeMax() throws PlanningException { TreeMap<Long, Resource> a = new TreeMap<>(); TreeMap<Long, Resource> b = new TreeMap<>(); setupArrays(a, b); RLESparseResourceAllocation rleA = new RLESparseResourceAllocation(a, new DefaultResourceCalculator()); RLESparseResourceAllocation rleB = new RLESparseResourceAllocation(b, new DefaultResourceCalculator()); RLESparseResourceAllocation out = RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.max, 0, 60); System.out.println(out); long[] time = { 10, 20, 30, 40, 50, 60 }; int[] alloc = { 5, 10, 15, 20, 10 }; validate(out, time, alloc); }
@Test public void testMergeSubtract() throws PlanningException { TreeMap<Long, Resource> a = new TreeMap<>(); TreeMap<Long, Resource> b = new TreeMap<>(); setupArrays(a, b); RLESparseResourceAllocation rleA = new RLESparseResourceAllocation(a, new DefaultResourceCalculator()); RLESparseResourceAllocation rleB = new RLESparseResourceAllocation(b, new DefaultResourceCalculator()); RLESparseResourceAllocation out = RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.subtract, 0, 60); System.out.println(out); long[] time = { 10, 11, 20, 22, 30, 33, 43, 50, 60 }; int[] alloc = { 5, 0, 5, 0, 5, 0, 10, -10 }; validate(out, time, alloc); }
protected void initialize(Plan plan, ReservationId reservationId, ReservationDefinition reservation) throws PlanningException { // Get plan step & capacity capacity = plan.getTotalCapacity(); step = plan.getStep(); // Get job parameters (type, arrival time & deadline) jobType = reservation.getReservationRequests().getInterpreter(); jobArrival = stepRoundUp(reservation.getArrival(), step); jobDeadline = stepRoundDown(reservation.getDeadline(), step); // Initialize the plan modifications planModifications = new RLESparseResourceAllocation(plan.getResourceCalculator()); // Dirty read of plan load // planLoads are not used by other StageAllocators... and don't deal // well with huge reservation ranges planLoads = plan.getCumulativeLoadOverTime(jobArrival, jobDeadline); ReservationAllocation oldRes = plan.getReservationById(reservationId); if (oldRes != null) { planLoads = RLESparseResourceAllocation.merge( plan.getResourceCalculator(), plan.getTotalCapacity(), planLoads, oldRes.getResourcesOverTime(jobArrival, jobDeadline), RLEOperator.subtract, jobArrival, jobDeadline); } }
@Override public void validate(Plan plan, ReservationAllocation reservation) throws PlanningException { RLESparseResourceAllocation available = plan.getAvailableResourceOverTime( reservation.getUser(), reservation.getReservationId(), reservation.getStartTime(), reservation.getEndTime(), reservation.getPeriodicity()); // test the reservation does not exceed what is available try { RLESparseResourceAllocation ask = reservation.getResourcesOverTime( reservation.getStartTime(), reservation.getEndTime()); RLESparseResourceAllocation .merge(plan.getResourceCalculator(), plan.getTotalCapacity(), available, ask, RLESparseResourceAllocation.RLEOperator.subtractTestNonNegative, reservation.getStartTime(), reservation.getEndTime()); } catch (PlanningException p) { throw new ResourceOverCommitException( "Resources at time " + reservation.getStartTime() + " would be overcommitted by accepting reservation: " + reservation.getReservationId(), p); } }
RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.subtractTestNonNegative, 0, 60); RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.subtractTestNonNegative, 0, 60); RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.subtractTestNonNegative, 0, 60); RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.subtractTestNonNegative, 0, 60); RLESparseResourceAllocation.merge(new DefaultResourceCalculator(), Resource.newInstance(100 * 128 * 1024, 100 * 32), rleA, rleB, RLEOperator.subtractTestNonNegative, 0, 60);
RLESparseResourceAllocation.merge(nonPeriodic.getResourceCalculator(), Resource.newInstance(100 * 1024, 100), periodic, nonPeriodic, RLESparseResourceAllocation.RLEOperator.add, 2, 25);