package test.rewolucja.reservation; import gridsim.gssim.policy.InExecuionList; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.joda.time.DateTime; import org.qcg.broker.schemas.resreqs.ExecutionTimeType; import schedframe.exceptions.ModuleException; import schedframe.exceptions.ReservationException; import schedframe.resources.ResourceDescription; import schedframe.resources.ResourceProvider; import schedframe.resources.ResourceStateDescription; import schedframe.resources.providers.LocalSystem; import schedframe.resources.units.Processors; import schedframe.resources.units.ResourceUnit; import schedframe.scheduling.AbstractResourceRequirements; import schedframe.scheduling.AbstractTimeRequirements; import schedframe.scheduling.Offer; import schedframe.scheduling.Queue; import schedframe.scheduling.ResourceRequirements; import schedframe.scheduling.ResourceUsage; import schedframe.scheduling.TaskInterface; import schedframe.scheduling.TimeRequirements; import schedframe.scheduling.TimeResourceAllocation; import schedframe.scheduling.plugin.grid.ModuleType; import schedframe.scheduling.plugin.local.LocalReservationManager; import schedframe.scheduling.plugin.local.TimeOperations; import schedframe.scheduling.utils.ResourceParameterName; import simulator.utils.MergeSort; import test.rewolucja.GSSIMJobInterface; import test.rewolucja.reservation.ReservationNew.Status; import test.rewolucja.resources.ProcessingElements; import test.rewolucja.resources.ResourceStatus; import test.rewolucja.resources.ResourceType; import test.rewolucja.resources.manager.implementation.ResourceManager; import test.rewolucja.resources.manager.interfaces.ResourceManagerInterface; import test.rewolucja.resources.physical.base.ComputingResource; import test.rewolucja.resources.physical.implementation.Processor; public class LocalReservationManagerNew implements LocalReservationManager { protected static Log log = LogFactory.getLog(LocalReservationManagerNew.class); protected ReservationListNew reservationList; protected TimeOperations timeOpers; protected long timeDelta; protected ResourceProvider resourceProvider; public LocalReservationManagerNew(long timeDelta, String resourceName) { this.timeDelta = timeDelta; this.timeOpers = new TimeOperations(timeDelta); this.reservationList = new GssimReservationListNew(); this.resourceProvider = new LocalSystem(resourceName , null, null); } public LocalReservationManagerNew(long timeDelta, TimeOperations timeOpers, String resourceName) { this.timeDelta = timeDelta; this.timeOpers = timeOpers; this.reservationList = new GssimReservationListNew(); this.resourceProvider = new LocalSystem(resourceName , null, null); } /** * Find the first free slot with regard to given resources and according to time requirements * @throws NoSuchFieldException */ public TimeResourceAllocation findFreeSlot(ExecutionTimeType time, ResourceUnit resReqs, ResourceUnit[] resStates) throws NoSuchFieldException { if (time == null) return null; DateTime currentTime = timeOpers.getTime();//Calendar.getInstance(); //start of period DateTime startPeriod = timeOpers.getTime();//Calendar.getInstance(); if (time.getTimePeriod() != null) if (time.getTimePeriod().getPeriodStart() != null) startPeriod = new DateTime(time.getTimePeriod().getPeriodStart().getTime()); //end of period DateTime endPeriod = new DateTime(Long.MAX_VALUE);//timeOpers.getTime();//Calendar.getInstance(); //endPeriod.setTimeInMillis(Long.MAX_VALUE); if (time.getTimePeriod() != null) if (time.getTimePeriod().getTimePeriodChoice() != null) if (time.getTimePeriod().getTimePeriodChoice().getPeriodEnd() != null) { endPeriod = new DateTime(time.getTimePeriod().getTimePeriodChoice().getPeriodEnd().getTime()); } else if (time.getTimePeriod().getTimePeriodChoice().getPeriodDuration() != null) endPeriod = new DateTime(startPeriod.getMillis() + time.getTimePeriod().getTimePeriodChoice().getPeriodDuration().toLong()); //days of the week boolean[] weekDays = new boolean[7]; ArrayList inclDates = null; ArrayList exclDates = null; if (time.getTimePeriod() != null) { //all weekdays allowed for (int i=0; i < 7; i++) weekDays[i] = true; if (time.getTimePeriod().getIncluding() != null) { //only weekdays defined in Including element allowed for (int i=0; i < 7; i++) weekDays[i] = false; for (int i=0; i < time.getTimePeriod().getIncluding().getDaysTypeItemCount(); i++) { if (time.getTimePeriod().getIncluding().getDaysTypeItem(i).getWeekDay() != null) { int day = time.getTimePeriod().getIncluding().getDaysTypeItem(i).getWeekDay().ordinal(); weekDays[(day+1)%7] = true; } else { org.exolab.castor.types.Date dateDay = time.getTimePeriod().getIncluding().getDaysTypeItem(i).getDateDay(); if (time.getTimePeriod().getIncluding().getDaysTypeItem(i).getDateDay() != null) { if (inclDates == null) inclDates = new ArrayList(); inclDates.add(new DateTime(dateDay.toLong())); } } } } if (time.getTimePeriod().getExcluding() != null) { for (int i=0; i < time.getTimePeriod().getExcluding().getDaysTypeItemCount(); i++) { if (time.getTimePeriod().getExcluding().getDaysTypeItem(i).getWeekDay() != null) { int day = time.getTimePeriod().getExcluding().getDaysTypeItem(i).getWeekDay().ordinal(); weekDays[(day+1)%7] = false; } else { org.exolab.castor.types.Date dateDay = time.getTimePeriod().getExcluding().getDaysTypeItem(i).getDateDay(); if (time.getTimePeriod().getExcluding().getDaysTypeItem(i).getDateDay() != null) { if (exclDates == null) exclDates = new ArrayList(); exclDates.add(new DateTime(dateDay.toLong())); } } } } //find latest possible date DateTime latestDate = timeOpers.findLatestDate(inclDates, exclDates); if (timeOpers.beforeDate(latestDate, endPeriod)) { endPeriod = timeOpers.setDate(endPeriod, latestDate); //endPeriod.set(Calendar.DAY_OF_MONTH, endPeriod.get(Calendar.DAY_OF_MONTH) + 1); endPeriod = endPeriod.plusDays(1); } } //time slot DateTime startTime = null; DateTime endTime = null; if (time.getTimeSlot() != null) { //start of time slot if (time.getTimeSlot().getSlotStart() != null){ //startTime = timeOpers.getTime();//Calendar.getInstance(); startTime = new DateTime(time.getTimeSlot().getSlotStart(). getContent().toDate().getTime()); } //end of time slot if (time.getTimeSlot().getTimeSlotChoice() != null) if (time.getTimeSlot().getTimeSlotChoice().getSlotEnd() != null){ //endTime = timeOpers.getTime();//Calendar.getInstance(); endTime = new DateTime(time.getTimeSlot().getTimeSlotChoice(). getSlotEnd().toDate().getTime()); } else if (time.getTimeSlot().getTimeSlotChoice().getSlotDuration() != null){ //endTime = timeOpers.getTime();//Calendar.getInstance(); endTime = new DateTime(time.getTimeSlot().getTimeSlotChoice(). getSlotDuration().toLong()); } } //duration long duration = time.getExecutionDuration().toLong(); //find a first free slot TimeResourceAllocation firstSlot = null; DateTime firstStartTime = (startTime != null) ? new DateTime(startTime) : timeOpers.getTime();//Calendar.getInstance(); for (int i=0; i < resStates.length; i++) { TimeResourceAllocation slot = findFreeHostSlot(resReqs, duration, startTime, endTime, startPeriod, endPeriod, weekDays, inclDates, exclDates, resStates[i]); if (firstSlot == null) firstSlot = slot; if (slot != null) { //if (firstSlot.getStartTime() > slot.getStartTime()) if(firstSlot.getStart().isAfter(slot.getStart())) firstSlot = slot; if (firstSlot.getStartMillis() <= Math.max(firstStartTime.getMillis(), currentTime.getMillis()) + timeDelta) return firstSlot; } } return firstSlot; } /** * Find the required free slot * @throws NoSuchFieldException */ public TimeResourceAllocation findFreeSlot(TimeResourceAllocation timeReq, ResourceUnit resReqs, ResourceUnit[] resStates) throws NoSuchFieldException { if (timeReq == null) return null; DateTime currentTime = timeOpers.getTime();//Calendar.getInstance(); //start of period DateTime startPeriod = timeReq.getStart(); //end of period DateTime endPeriod = timeReq.getEnd(); //days of the week boolean[] weekDays = new boolean[7]; ArrayList inclDates = null; ArrayList exclDates = null; //all weekdays allowed for (int i=0; i < 7; i++) weekDays[i] = true; //find latest possible date DateTime latestDate = timeOpers.findLatestDate(inclDates, exclDates); if (timeOpers.beforeDate(latestDate, endPeriod)) { endPeriod = new DateTime(latestDate.getYear(), latestDate.getMonthOfYear(), latestDate.getDayOfMonth() + 1, endPeriod.getHourOfDay(), endPeriod.getMinuteOfHour(), endPeriod.getSecondOfMinute(), endPeriod.getMillisOfSecond(), endPeriod.getChronology());//timeOpers.setDate(endPeriod, latestDate); // endPeriod.set(Calendar.DAY_OF_MONTH, endPeriod.get(Calendar.DAY_OF_MONTH) + 1); } //time slot DateTime startTime = null; DateTime endTime = null; //start of time slot startTime = timeReq.getStart(); //end of time slot endTime = timeReq.getEnd(); //duration long duration = timeReq.getEndMillis() - timeReq.getStartMillis() - timeDelta; //find a first free slot TimeResourceAllocation firstSlot = null; DateTime firstStartTime = (startTime!=null)? new DateTime(startTime) : timeOpers.getTime();//Calendar.getInstance(); for (int i=0; i < resStates.length; i++) { TimeResourceAllocation slot = findFreeHostSlot(resReqs, duration, startTime, endTime, startPeriod, endPeriod, weekDays, inclDates, exclDates, resStates[i]); if (firstSlot == null) firstSlot = slot; if (slot != null) { // if (firstSlot.getStartTime() > slot.getStartTime()) if (firstSlot.getStart().isAfter(slot.getStart())) firstSlot = slot; if (firstSlot.getStartMillis() <= Math.max(firstStartTime.getMillis(), currentTime.getMillis()) + timeDelta) return firstSlot; } } return firstSlot; } /** * Find the first free slot according to time requirements */ public TimeResourceAllocation findFreeSlot(ExecutionTimeType time) { if (time == null) return null; DateTime currentTime = timeOpers.getTime();//Calendar.getInstance(); //start of period DateTime startPeriod = timeOpers.getTime();//Calendar.getInstance(); if (time.getTimePeriod() != null) if (time.getTimePeriod().getPeriodStart() != null) //startPeriod.setTimeInMillis(time.getTimePeriod().getPeriodStart().getTime()); startPeriod = new DateTime(time.getTimePeriod().getPeriodStart().getTime()); //end of period DateTime endPeriod = new DateTime(Long.MAX_VALUE);//timeOpers.getTime();//Calendar.getInstance(); //endPeriod.setTimeInMillis(Long.MAX_VALUE); if (time.getTimePeriod() != null) if (time.getTimePeriod().getTimePeriodChoice() != null) if (time.getTimePeriod().getTimePeriodChoice().getPeriodEnd() != null) { //endPeriod.setTimeInMillis(time.getTimePeriod().getTimePeriodChoice().getPeriodEnd().getTime()); endPeriod = new DateTime(time.getTimePeriod().getTimePeriodChoice().getPeriodEnd().getTime()); } else if (time.getTimePeriod().getTimePeriodChoice().getPeriodDuration() != null) //endPeriod.setTimeInMillis(startPeriod.getTimeInMillis() + time.getTimePeriod().getTimePeriodChoice().getPeriodDuration().toLong()); endPeriod = new DateTime(startPeriod.getMillis() + time.getTimePeriod().getTimePeriodChoice().getPeriodDuration().toLong()); //days of the week boolean[] weekDays = new boolean[7]; ArrayList inclDates = null; ArrayList exclDates = null; //all weekdays allowed for (int i=0; i < 7; i++) weekDays[i] = true; if (time.getTimePeriod() != null) { if (time.getTimePeriod().getIncluding() != null) { //only weekdays defined in Including element allowed for (int i=0; i < 7; i++) weekDays[i] = false; for (int i=0; i < time.getTimePeriod().getIncluding().getDaysTypeItemCount(); i++) { if (time.getTimePeriod().getIncluding().getDaysTypeItem(i).getWeekDay() != null) { int day = time.getTimePeriod().getIncluding().getDaysTypeItem(i).getWeekDay().ordinal(); weekDays[(day+1)%7] = true; } else { org.exolab.castor.types.Date dateDay = time.getTimePeriod().getIncluding().getDaysTypeItem(i).getDateDay(); if (dateDay != null) { if (inclDates == null) inclDates = new ArrayList(); inclDates.add(new DateTime(dateDay)); } } } } if (time.getTimePeriod().getExcluding() != null) { for (int i=0; i < time.getTimePeriod().getExcluding().getDaysTypeItemCount(); i++) { if (time.getTimePeriod().getExcluding().getDaysTypeItem(i).getWeekDay() != null) { int day = time.getTimePeriod().getExcluding().getDaysTypeItem(i).getWeekDay().ordinal(); weekDays[(day+1)%7] = false; } else { org.exolab.castor.types.Date dateDay = time.getTimePeriod().getExcluding().getDaysTypeItem(i).getDateDay(); if (time.getTimePeriod().getExcluding().getDaysTypeItem(i).getDateDay() != null) { if (exclDates == null) exclDates = new ArrayList(); exclDates.add(new DateTime(dateDay)); } } } } //find latest possible date DateTime latestDate = timeOpers.findLatestDate(inclDates, exclDates); if (timeOpers.beforeDate(latestDate, endPeriod)) { endPeriod = timeOpers.setDate(endPeriod, latestDate); //endPeriod.set(Calendar.DAY_OF_MONTH, endPeriod.get(Calendar.DAY_OF_MONTH) + 1); endPeriod = endPeriod.plusDays(1); } } //start of time slot DateTime startSlot = null; DateTime endSlot = null; if (time.getTimeSlot() != null) { if (time.getTimeSlot().getSlotStart() != null){ //startSlot = timeOpers.getTime();//Calendar.getInstance(); startSlot = new DateTime(time.getTimeSlot().getSlotStart(). getContent().toDate().getTime()); } //end of time slot if (time.getTimeSlot().getTimeSlotChoice() != null) if (time.getTimeSlot().getTimeSlotChoice().getSlotEnd() != null){ //endSlot = timeOpers.getTime();//Calendar.getInstance(); endSlot = new DateTime(time.getTimeSlot().getTimeSlotChoice(). getSlotEnd().toDate().getTime()); } else if (time.getTimeSlot().getTimeSlotChoice().getSlotDuration() != null){ //endSlot = timeOpers.getTime();//Calendar.getInstance(); endSlot = new DateTime(time.getTimeSlot().getTimeSlotChoice(). getSlotDuration().toLong()); } } //duration long duration = time.getExecutionDuration().toLong(); //if task duration longer than slot length if (startSlot != null && endSlot != null) if (duration + timeDelta > timeOpers.periodDayTimeDuration(startSlot, endSlot)) return null; boolean inclDay = false; //check if there are any not excluded weekdays if (inclDates == null) { for (int i=0; i < 7; i++) if (weekDays[i] == true) inclDay = true; }//check if there are included dates later than startPeriod else { for (int i=0; i < inclDates.size(); i++) if (startPeriod.isBefore(inclDates.get(i))) inclDay = true; } if (!inclDay) return null; DateTime startTime = null; //timeOpers.getTime();//Calendar.getInstance(); //start from startPeriod startTime = new DateTime(Math.max(startPeriod.getMillis(), currentTime.getMillis())); if (startSlot != null) if (timeOpers.beforePeriodDayTime(startTime, startSlot, endSlot)) startTime = timeOpers.setDayTime(startTime, startSlot); //start from startSlot while (!meetTimeRequirements(startTime, duration, startSlot, endSlot, weekDays, inclDates, exclDates, endPeriod)) { if (!timeOpers.withinPeriod(duration, startTime, endPeriod)) return null; nextSlot(startTime, duration, startSlot, endSlot); } DateTime cStart = new DateTime(startTime.getMillis() + timeDelta); DateTime cEnd = new DateTime(startTime.getMillis() + timeDelta + duration); TimeResourceAllocation slot = new TimeResourceAllocation(cStart, cEnd); return slot; } /** * Find the free slots concerning given resources and according to time requirements */ public TimeResourceAllocation[] findFreeSlots(ExecutionTimeType time, ResourceUnit resReqs, ResourceUnit[] resStates) { //TODO return null; } /** * Checks whether a given slot meets requirements * @param slot a given slot * @param resReqs requirement * @param resStates states of resources * @return true if slot is free * @throws NoSuchFieldException */ /* public boolean isSlotFree(TimeResourceAllocation slot, ResourceUnit resReqs, ResourceUnit[] resStates) throws NoSuchFieldException { if (slot == null) return false; if (resStates == null || resStates.length == 0) return false; if (resReqs == null) resReqs = new DiscreteProcessors(1, 0); ResourceUnit totalResource = null; for (int i=0; i < resStates.length; i++) { if (resStates[i].getName() == resReqs.getName()) { totalResource = resStates[i]; break; } } if (totalResource == null) return false; TimeResourceAllocation[] usage = resourceUsage(totalResource, slot.getStart(), slot.getEnd()); try { for (int i=0; i < usage.length; i++){ float usedResources = 0; usedResources = totalResource.getAmount() - usage[i].getAllocatedResource().getProcessorsAmount(); /* if(usage[i].getResourceUnit(Constants.PE).getResourceUnitType() == ResourceUnitType.DISCRETE_RESOURCE){ usedResources = usage[i].getResourceUnit(Constants.PE).getAmount(); } else { usedResources = totalResource.getAmount() - usage[i].getResourceUnit(Constants.PE).getAmount(); } */ /* if(resReqs.getResourceUnitType() == ResourceUnitType.DISCRETE_RESOURCE){ DiscreteProcessors discResReq = (DiscreteProcessors) resReqs; DiscreteProcessors avlUnit = (DiscreteProcessors)usage[i]. getAllocatedResource(). getResourceUnit(ResourceParameterName.CPUCOUNT); for(int j = 0; j < discResReq.getAmount(); j++){ // request availability of processor which is not available //if(reqAvl[j] == Avl.REQUESTED && avl[j] == Avl.USED){ if(discResReq.getStatus(j) == Avl.USED && avlUnit.getStatus(j) == Avl.USED){ return false; } } } else { //if (totalResource.getAmount() - usage[i].getResourceUnit().getAmount() < resReqs.getAmount()) // return false; if(usedResources < resReqs.getAmount()) return false; } } } catch(NoSuchFieldException e){ log.error(e.getMessage()); return false; } //TODO check specific resources for discrete resource units, e.g. number of processors! return true; } */ public String reserveResource(String jobID, String taskID, String userID, ExecutionTimeType time, ResourceUnit resReqs, ResourceUnit[] resStates) throws NoSuchFieldException { TimeResourceAllocation slot = findFreeSlot(time, resReqs, resStates); if (slot == null) return null; return addReservation(slot.getStart(), slot.getEnd(), jobID, taskID, userID, slot.getAllocatedResource()); } public boolean cancelReservation(String reservId) { if (setReservStatus(reservId, ReservationNew.Status.CANCELED) == Status.CANCELED) return true; return false; } public int clearReservations() { int n = reservationList.size(); reservationList.clear(); return n; } public String addReservation(DateTime startTime, DateTime finishTime, String jobId, String taskId, String userId, ResourceDescription resources) { //TODO check if reservation can be added (take into account specific resources for discrete resource units, e.g. number of processors!) ReservationNew res = new ReservationNew(resources, startTime, finishTime, null); res.setJobId(jobId); res.setTaskId(taskId); res.setUserId(userId); reservationList.add(res); return res.getId(); } public String addReservation(ReservationNew res) { //TODO check if reservation can be added (take into account specific resources for discrete resource units, e.g. number of processors!) reservationList.add(res); return res.getId(); } public ReservationNew getReservation(String reservId) { for (int i=0; i < reservationList.size(); i++) { if (((ReservationNew)reservationList.get(i)).getId().equals(reservId)) return (ReservationNew)reservationList.get(i); } return null; } public Status getReservStatus(String reservId) { ReservationNew res = getReservation(reservId); if (res == null) throw new IllegalArgumentException("There is no reservation with id " + reservId); return res.getStatus(); } public Status setReservStatus(String reservId, Status status) { ReservationNew res = getReservation(reservId); if (res == null) throw new IllegalArgumentException("There is no reservation with id " + reservId); Status st = res.getStatus(); res.setStatus(status); return st; } /** * @return identifiers of jobs that have to be started */ public String[] checkJobsToStart() { //TODO Get jobInfos from registry (maybe in constructor) //TODO Construct generic reservation manager long currentTime = timeOpers.getTime().getMillis(); ArrayList v = new ArrayList(); for (int i=0; i < reservationList.size(); i++) { if (((ReservationNew)reservationList.get(i)).getStatus() == ReservationNew.Status.COMMITTED) if (((ReservationNew)reservationList.get(i)).getStart().getMillis() > currentTime - timeDelta) v.add(((ReservationNew)reservationList.get(i)).getId()); } if (v.size() == 0) return null; String[] resIds = new String[v.size()]; resIds = (String[])v.toArray(resIds); return resIds; } /** * @return identifiers of jobs that have to be stopped */ public String[] checkJobsToStop() { //TODO Get jobInfos from registry (maybe in constructor) //TODO Construct generic reservation manager long currentTime = timeOpers.getTime().getMillis(); ArrayList v = new ArrayList(); for (int i=0; i < reservationList.size(); i++) { if (((ReservationNew)reservationList.get(i)).getStatus() == ReservationNew.Status.ACTIVE) if (((ReservationNew)reservationList.get(i)).getEnd().getMillis() > currentTime - timeDelta) v.add(((ReservationNew)reservationList.get(i)).getId()); } if (v.size() == 0) return null; String[] resIds = new String[v.size()]; resIds = (String[])v.toArray(resIds); return resIds; } /** * * @uml.property name="timeDelta" */ public long getTimeDelta() { return timeDelta; } /** * * @uml.property name="timeDelta" */ public void setTimeDelta(long timeDelta) { this.timeDelta = timeDelta; timeOpers.setTimeDelta(timeDelta); } public void setTimeOperations(TimeOperations timeOpers) { this.timeOpers = timeOpers; } public boolean prolongReservation(String reservID, DateTime newEndTime, ResourceUnit resAvail) throws Exception { ReservationNew reserv = getReservation(reservID); if (reserv == null) return false; TimeResourceAllocation s = reserv; if (s == null) return false; ResourceUnit resource = s.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); if (resource == null) return false; if (newEndTime.getMillis() <= s.getEnd().getMillis()){ s.setEnd(newEndTime); return true; } TimeResourceAllocation[] slots = resourceUsage(resource, s.getEnd(), newEndTime); if (slots == null) { s.setEnd(newEndTime); return true; } for (int i=0; i < slots.length; i++) { ResourceUnit res = slots[i].getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); if (res.getAmount() + resource.getAmount() > resAvail.getAmount())//not enough resources return false; } s.setEnd(newEndTime); return true; } /** * Creates a list of time slots with usage of given resource type * Slots reflect time periods within which resource usage is constant * @param resourceUnit only two parameters of this object are used, type - which should be * the same type handled by this particular ReservationManager and resource id. Unit amount * is not used by this method, therefore this value may be set to 0 or null. * @param startTime begin of the time period within which resource usage should be calculated * @param endTime end of the time period within which resource usage should be calculated * @return list of time slots with various resource usage * @throws NoSuchFieldException */ public ArrayList resourceUsageList(ResourceUnit resourceUnit, DateTime startTime, DateTime endTime) throws NoSuchFieldException { String rmc = resourceUnit.getResourceId(); //Create a list of slots based on existing reservations that haven't been completed ArrayList v = new ArrayList(); for (int i=0; i < reservationList.size(); i++) { ReservationNew r =(ReservationNew)reservationList.get(i); if (r == null) continue; if (r.getStatus() != ReservationNew.Status.INITIAL && r.getStatus() != ReservationNew.Status.COMMITTED && r.getStatus() != ReservationNew.Status.ACTIVE) continue; if(!rmc.equals(r.getResourceName())) continue; TimeResourceAllocation orgSlot = r; if (orgSlot == null) continue; // sprawdzic jak to sie zachowa gdy rezerwacje przyjda dla ResUnit typu continous TimeResourceAllocation reserverdSlot = new TimeResourceAllocation( (ResourceDescription)orgSlot.getAllocatedResource().clone(), orgSlot.getStart(), orgSlot.getEnd()); // reserved slot ends before requested period starts if (reserverdSlot.getEnd().getMillis() <= startTime.getMillis()) continue; // reserved slot starts after requested period ends if (reserverdSlot.getStart().getMillis() >= endTime.getMillis()) break; //slot partially before requested period if (reserverdSlot.getStart().isBefore(startTime)){ reserverdSlot = new TimeResourceAllocation(reserverdSlot); reserverdSlot.setStart(startTime); } // first reserved slot starts after begin of the requested time period, which means that // resource between start time of requested time period and start time of first reservation // is not used. if (v.size() == 0) if (reserverdSlot.getStart().isAfter(startTime)) { ResourceUnit ru = (ResourceUnit)resourceUnit.clone(); ru.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(ru); v.add(new TimeResourceAllocation(rd, startTime, reserverdSlot.getStart())); } //slot partially after requested period TimeResourceAllocation oldSlot; if (reserverdSlot.getEnd().isAfter(endTime)) { oldSlot = reserverdSlot; reserverdSlot = new TimeResourceAllocation(oldSlot); reserverdSlot.setEnd(endTime); } v.add(reserverdSlot); } //if there is no resource usage in the requested period if (v.size() == 0) { ResourceUnit ru = (ResourceUnit) resourceUnit.clone(); ru.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(ru); v.add(new TimeResourceAllocation(rd, startTime, endTime)); } else { //last slot ends before end of the requested period TimeResourceAllocation slot = (TimeResourceAllocation)v.get(v.size() - 1); //last slot if (slot.getEnd().isBefore(endTime)) { ResourceUnit ru = (ResourceUnit) resourceUnit.clone(); ru.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(ru); v.add(new TimeResourceAllocation(rd, slot.getEnd(), endTime)); } } //Find gaps between slots and overlapping slots, and based on them generate additional slots int i = 0; while (i < v.size()) { TimeResourceAllocation previousSlot = (TimeResourceAllocation)v.get(i); TimeResourceAllocation slot = (TimeResourceAllocation)v.get(i); if (i + 1 < v.size()) slot = (TimeResourceAllocation)v.get(i + 1); else break; if(slot.getStart().compareTo(previousSlot.getEnd()) == 0) // one slot immediately after another i++; else if (slot.getStart().isAfter(previousSlot.getEnd())) { // there is a gap between two slots ResourceUnit resUsage = (ResourceUnit) resourceUnit.clone(); resUsage.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resUsage); TimeResourceAllocation slot1 = new TimeResourceAllocation(rd, previousSlot.getEnd(), slot.getStart()); v.add(++i, slot1); } else { // slots overlap (slot.getStartTime() < lastSlot.getEndTime()) DateTime start = previousSlot.getStart(); DateTime newStart = slot.getStart(); long lnewEnd = Math.min(previousSlot.getEnd().getMillis(),slot.getEnd().getMillis()); DateTime newEnd = new DateTime(lnewEnd); long lend = Math.max(previousSlot.getEnd().getMillis(),slot.getEnd().getMillis()); DateTime end = new DateTime(lend); ResourceDescription resUsage = (ResourceDescription) previousSlot.getAllocatedResource().clone(); TimeResourceAllocation slot1 = new TimeResourceAllocation(resUsage, start, newStart); resUsage = (ResourceDescription) previousSlot.getAllocatedResource().clone(); // mark processors which are unavailable in slot.resourceUnit as unavailable also in resUsage.resourceUnit object. // this should be a synonym for: previousSlot.getResourceUnit().getAmount()+slot.getResourceUnit().getAmount() { ResourceUnit unit = resUsage.getResourceUnit(ResourceParameterName.CPUCOUNT); if(unit instanceof List){ List peResUsage = (List) unit; ResourceUnit resUnit = slot.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); if(resUnit instanceof List){ List disResUnit = (List) resUnit; for(int a = 0; a < disResUnit.size(); a++){ Processor p = disResUnit.get(a); if(p.getStatus() == ResourceStatus.BUSY){ peResUsage.get(a).setStatus(ResourceStatus.BUSY); } else if(p.getStatus() == ResourceStatus.RESERVED){ peResUsage.get(a).setStatus(ResourceStatus.RESERVED); } } } else { log.warn("CHECK AND WERIFY IF THIS CODE IS CORRECT"); int cnt = Float.valueOf(resUnit.getAmount()).intValue(); for(int a = 0; a < peResUsage.size() && cnt > 0; a++){ if(peResUsage.get(a).getStatus() == ResourceStatus.FREE){ peResUsage.get(a).setStatus(ResourceStatus.BUSY); cnt--; } } } } else { ResourceUnit prevResUnit = previousSlot.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); ResourceUnit resUnit = slot.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); ResourceUnit usedUnit = resUsage.getResourceUnit(ResourceParameterName.CPUCOUNT); usedUnit.setUsedAmount(prevResUnit.getUsedAmount() + resUnit.getUsedAmount()); } } TimeResourceAllocation slot2 = new TimeResourceAllocation(resUsage, newStart, newEnd); if (previousSlot.getEnd().isAfter(slot.getEnd())) { resUsage = (ResourceDescription) previousSlot.getAllocatedResource().clone(); } else { resUsage = (ResourceDescription) slot.getAllocatedResource().clone(); } TimeResourceAllocation slot3 = new TimeResourceAllocation(resUsage, newEnd, end); if (newEnd.compareTo(end) != 0){ int j=i+2; while ((j < v.size()) && (newEnd.isAfter(((TimeResourceAllocation)v.get(j)).getStart()))) j++; v.add(j, slot3); } v.remove(previousSlot); v.remove(slot); if (start.compareTo(newStart) != 0) { v.add(i++, slot1); v.add(i, slot2); } else {//equal start times of slots TimeResourceAllocation tra = null; float amount = -1; if (i > 0) { tra = (TimeResourceAllocation)v.get(i-1); amount = tra.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT).getUsedAmount(); } if (amount == slot2.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT).getUsedAmount()) { //two subsequent slots with equal resource usage tra.setEnd(slot2.getEnd()); //extend previous slot i--; } else v.add(i, slot2); }//equal start times of slots } } if (v.size() == 0){ if(log.isErrorEnabled()) log.error(getClass().getName()+" resourceUsage() - end, v.size = 0"); return null; } return v; } /** * Creates a list of time slots with usage of given resource type * Slots reflect time periods within which resource usage is constant * @return list of time slots with various resource usage * @throws NoSuchFieldException */ public TimeResourceAllocation[] resourceUsage(ResourceUnit resourceUnit, DateTime startTime, DateTime endTime) throws NoSuchFieldException { ArrayList al; al = resourceUsageList(resourceUnit, startTime, endTime); if (al == null) return null; TimeResourceAllocation[] slot = new TimeResourceAllocation[al.size()]; slot = (TimeResourceAllocation[])al.toArray(slot); return slot; } /** * Find first free slot for the selected host * @throws NoSuchFieldException */ public TimeResourceAllocation findFreeHostSlot( ResourceUnit resReq, long duration, DateTime startSlot, DateTime endSlot, DateTime startPeriod, DateTime endPeriod, boolean[] weekDays, ArrayList inclDates, ArrayList exclDates, ResourceUnit resource) throws NoSuchFieldException { if (resource.getName() != resReq.getName()) return null; if (resReq.getAmount() > resource.getAmount()) return null; /* ResourceUnit resDest = new ResourceUnit(resource.getResourceId(), resource.getResUnitName(), resReq.getAmount()); resDest.setLocalInterfaceType(resource.getLocalInterfaceType()); resDest.setValues(resource.getValues()); */ ResourceUnit resDest = (ResourceUnit)resource.clone(); DateTime currentTime = timeOpers.getTime();//Calendar.getInstance(); DateTime startTime = null; //timeOpers.getTime();//Calendar.getInstance(); //start from startPeriod startTime = new DateTime(Math.max(startPeriod.getMillis(), currentTime.getMillis())); if (startSlot != null) if (timeOpers.beforePeriodDayTime(startTime, startSlot, endSlot)) startTime = timeOpers.setDayTime(startTime, startSlot); long startTimeLong = startTime.getMillis(); if ((startSlot != null) && (endSlot != null)) { long endSlotLong = endSlot.getMillis(); if (endSlotLong < startSlot.getMillis()) { endSlot = endSlot.plusHours(24); endSlotLong = endSlot.getMillis(); } //if task duration longer than slot length if (duration + timeDelta > endSlotLong - startSlot.getMillis()) return null; } boolean inclDay = false; //check if there are not excluded weekdays if (inclDates == null) { for (int i=0; i < 7; i++) if (weekDays[i] == true) inclDay = true; }//check if there are included dates later than startPeriod else { for (int i=0; i < inclDates.size(); i++) if (startPeriod.isBefore(inclDates.get(i))) inclDay = true; } if (!inclDay) return null; //start from startSlot while (!meetTimeRequirements(startTime, duration, startSlot, endSlot, weekDays, inclDates, exclDates, endPeriod) && timeOpers.withinPeriod(duration, startTime, endPeriod)) { nextSlot(startTime, duration, startSlot, endSlot); startTimeLong = startTime.getMillis(); } //while still in period while (timeOpers.withinPeriod(duration, startTime, endPeriod)) { DateTime startTimeCal = new DateTime(startTimeLong); DateTime endTimeCal = new DateTime(Long.MAX_VALUE); TimeResourceAllocation[] slot = resourceUsage(resource, startTimeCal, endTimeCal); if (slot == null) { startTimeCal = new DateTime(startTimeLong + timeDelta); endTimeCal = new DateTime(startTimeLong + timeDelta + duration); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resDest); return new TimeResourceAllocation(rd, startTimeCal, endTimeCal); } for (int i = 0; i < slot.length; i++) { float freeRes = 0; ResourceUnit resUnit = slot[i].getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); freeRes = resUnit.getFreeAmount(); if (startTimeLong + timeDelta + duration < slot[i].getStart().getMillis()) { startTimeCal = new DateTime(startTimeLong + timeDelta); endTimeCal = new DateTime(startTimeLong + timeDelta + duration); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resDest); return new TimeResourceAllocation(rd, startTimeCal, endTimeCal); } // else if (resReq.getAmount() <= resource.getAmount() - slot[i].getResourceUnit(Constants.PE).getAmount()) { else if(resReq.getAmount() <= freeRes) { if (startTimeLong + timeDelta + duration < slot[i].getEnd().getMillis() || i == slot.length - 1) { startTimeCal = new DateTime(startTimeLong + timeDelta); endTimeCal = new DateTime(startTimeLong + timeDelta + duration); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resDest); return new TimeResourceAllocation(rd, startTimeCal, endTimeCal); } } else { startTimeLong = slot[i].getEnd().getMillis(); startTime = new DateTime(startTimeLong); } //check if still in slot if (!timeOpers.withinPeriodDayTime(startTime, duration, startSlot, endSlot)) { do { nextSlot(startTime, duration, startSlot, endSlot); startTimeLong = startTime.getMillis(); } while (!meetTimeRequirements(startTime, duration, startSlot, endSlot, weekDays, inclDates, exclDates, endPeriod) && timeOpers.withinPeriod(duration, startTime, endPeriod)); break; } // //check if still in period if (!timeOpers.withinPeriod(duration, startTime, endPeriod)) return null; // } } return null; } /** * Simple findFreeSlot * * @param resReq * @param duration * @param startPeriod * @param endPeriod * @param resource * @return * @throws NoSuchFieldException */ public TimeResourceAllocation findFreeSlot(ResourceUnit resReq, long duration, DateTime startPeriod, DateTime endPeriod, ResourceUnit resource) throws NoSuchFieldException { if (resource.getName() != resReq.getName()) return null; if (resReq.getAmount() > resource.getAmount()) return null; ResourceUnit resDest = (ResourceUnit) resource.clone(); DateTime currentTime = timeOpers.getTime(); DateTime startTime = null; // start from startPeriod startTime = new DateTime(Math.max(startPeriod.getMillis(), currentTime.getMillis())); long startTimeLong = startTime.getMillis(); DateTime slotStart = timeOpers.getTime(); DateTime slotEnd = timeOpers.getTime(); // get resource usage TimeResourceAllocation[] slot = resourceUsage(resource, startTime, endPeriod); // whole period free if (slot == null) { slotStart = new DateTime(startTimeLong + timeDelta); slotEnd = new DateTime(startTimeLong + timeDelta + duration); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resDest); return new TimeResourceAllocation(rd, slotStart, slotEnd); } int startSlot = 0; //binarySearch(startTime, slot); // otherwise browse slots for (int i = startSlot; i < slot.length; i++) { float freeRes = 0; ResourceUnit resUnit = slot[i].getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); freeRes = resource.getAmount() - resUnit.getUsedAmount(); // if requested slot can be reserved before start of the first slot from resource usage (TODO: is it possible - to look at resourceUsage) if (startTimeLong + timeDelta + duration < slot[i].getStart().getMillis()) { slotStart = new DateTime(startTimeLong + timeDelta); slotEnd = new DateTime(startTimeLong + timeDelta + duration); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resDest); return new TimeResourceAllocation(rd, slotStart, slotEnd); } // otherwise if there are enough resources in the current slot else if (resReq.getAmount() <= freeRes) { if (startTimeLong + timeDelta + duration < slot[i].getEnd().getMillis() || i == slot.length - 1) { slotStart = new DateTime(startTimeLong + timeDelta); slotEnd = new DateTime(startTimeLong + timeDelta + duration); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resDest); return new TimeResourceAllocation(rd, slotStart, slotEnd); } } else { startTimeLong = slot[i].getEnd().getMillis(); startTime = new DateTime(startTimeLong); } // check if still in period if (!timeOpers.withinPeriod(duration, startTime, endPeriod)) return null; } return null; } /** * * @param time * @param startPeriod * @param endPeriod * @return number of slot */ public int binarySearch(DateTime time, TimeResourceAllocation[] tra) { if (tra == null) return -1; int start = 0; int end = tra.length - 1; int slotNumber = -1; int pos = 0; while (slotNumber < 0) { pos = (end - start) / 2; if (pos == 0) { slotNumber = 0; break; } if (time.isBefore(tra[pos].getStart())) end = pos - 1; else if (time.isAfter(tra[pos].getEnd())) start = pos + 1; else if (time.isBefore(tra[pos - 1].getEnd())) end = pos - 1; else slotNumber = pos; } return slotNumber; } protected boolean meetTimeRequirements( DateTime startTime, long duration, DateTime startSlot, DateTime endSlot, boolean[] weekDays, ArrayList inclDates, ArrayList exclDates, DateTime endPeriod) { if (!timeOpers.withinPeriodDayTime(startTime, duration, startSlot, endSlot)) return false; //date not included if (inclDates != null) { if (!timeOpers.findDate(startTime, inclDates) && !weekDays[startTime.getDayOfWeek() - 1]) return false; } else //weekday not included or excluded if (!weekDays[startTime.getDayOfWeek() - 1]) return false; //date exluded if (timeOpers.findDate(startTime, exclDates)) return false; //deadline (endPeriod) exceeded if (!timeOpers.withinPeriod(duration, startTime, endPeriod)) return false; return true; } /** * Checks whether slot beginning at startTime and ending at startTime + duration * meets time requirements. * @param startTime * @param duration * @param reqDuration * @param startSlot * @param endSlot * @param weekDays * @param inclDates * @param exclDates * @param startPeriod * @param endPeriod * @return 0 if slot meets all requirements; 1 if slot meets all requirements but is too short; -1 otherwise */ protected int fitTimeSlot(DateTime startTime, long duration, long reqDuration, DateTime startSlot, DateTime endSlot, boolean[] weekDays, ArrayList inclDates, ArrayList exclDates, DateTime startPeriod, DateTime endPeriod) { // slot end before start of the requested period if (startTime.getMillis() + duration <= startPeriod.getMillis()) return -1; // deadline (endPeriod) exceeded //if (!timeOpers.withinPeriod(duration, startTime, endPeriod)) if (startTime.getMillis() >= endPeriod.getMillis()) return -1; if (!timeOpers.overlapPeriodDayTime(startTime, duration, startSlot, endSlot)) return -1; // date not included if (inclDates != null) { if (!timeOpers.findDate(startTime, inclDates) && !weekDays[startTime.getDayOfWeek() - 1]) return -1; } else // weekday not included or excluded if (!weekDays[startTime.getDayOfWeek() - 1]) return -1; // date exluded if (timeOpers.findDate(startTime, exclDates)) return -1; //calculate new duration if (startTime.getMillis() + duration > endPeriod.getMillis()) duration = endPeriod.getMillis() - startTime.getMillis(); if (timeOpers.afterDayTime(startTime, duration, endSlot)) { DateTime newEndTime = new DateTime(startTime.getMillis() + duration); newEndTime = timeOpers.setDayTime(newEndTime, endSlot); duration = newEndTime.getMillis() - startTime.getMillis(); } //slot is too short if (reqDuration > duration) return 1; return 0; } /** * Checks whether a reservation meeting time requirements within a given slot is possible. * @param slot * @param time * @return 0 if slot meets all requirements; 1 if slot meets all requirements but is too short; -1 otherwise */ public int fitTimeSlot(TimeResourceAllocation slot, ExecutionTimeType time) { if (time == null) return 0; //start of period DateTime startPeriod = timeOpers.getTime();//Calendar.getInstance(); if (time.getTimePeriod() != null) if (time.getTimePeriod().getPeriodStart() != null) startPeriod = new DateTime(time.getTimePeriod().getPeriodStart().getTime()); //end of period DateTime endPeriod = new DateTime(Long.MAX_VALUE); if (time.getTimePeriod() != null) if (time.getTimePeriod().getTimePeriodChoice() != null) if (time.getTimePeriod().getTimePeriodChoice().getPeriodEnd() != null) { endPeriod = new DateTime(time.getTimePeriod().getTimePeriodChoice().getPeriodEnd().getTime()); } else if (time.getTimePeriod().getTimePeriodChoice().getPeriodDuration() != null) endPeriod = new DateTime(startPeriod.getMillis() + time.getTimePeriod().getTimePeriodChoice().getPeriodDuration().toLong()); //days of the week boolean[] weekDays = new boolean[7]; ArrayList inclDates = null; ArrayList exclDates = null; //all weekdays allowed for (int i=0; i < 7; i++) weekDays[i] = true; if (time.getTimePeriod() != null) { if (time.getTimePeriod().getIncluding() != null) { //only weekdays defined in Including element allowed for (int i=0; i < 7; i++) weekDays[i] = false; for (int i=0; i < time.getTimePeriod().getIncluding().getDaysTypeItemCount(); i++) { if (time.getTimePeriod().getIncluding().getDaysTypeItem(i).getWeekDay() != null) { int day = time.getTimePeriod().getIncluding().getDaysTypeItem(i).getWeekDay().ordinal(); weekDays[(day+1)%7] = true; } else { org.exolab.castor.types.Date dateDay = time.getTimePeriod().getIncluding().getDaysTypeItem(i).getDateDay(); if (dateDay != null) { if (inclDates == null) inclDates = new ArrayList(); inclDates.add(new DateTime(dateDay.toLong())); } } } } if (time.getTimePeriod().getExcluding() != null) { for (int i=0; i < time.getTimePeriod().getExcluding().getDaysTypeItemCount(); i++) { if (time.getTimePeriod().getExcluding().getDaysTypeItem(i).getWeekDay() != null) { int day = time.getTimePeriod().getExcluding().getDaysTypeItem(i).getWeekDay().ordinal(); weekDays[(day+1)%7] = false; } else { org.exolab.castor.types.Date dateDay = time.getTimePeriod().getExcluding().getDaysTypeItem(i).getDateDay(); if (time.getTimePeriod().getExcluding().getDaysTypeItem(i).getDateDay() != null) { if (exclDates == null) exclDates = new ArrayList(); exclDates.add(new DateTime(dateDay.toLong())); } } } } //find latest possible date DateTime latestDate = timeOpers.findLatestDate(inclDates, exclDates); if (timeOpers.beforeDate(latestDate, endPeriod)) { endPeriod = timeOpers.setDate(endPeriod, latestDate); endPeriod = endPeriod.plusDays(1); //(Calendar.DAY_OF_MONTH, endPeriod.getDayOfMonth() + 1); } } //start of time slot DateTime startSlot = null; DateTime endSlot = null; if (time.getTimeSlot() != null) { if (time.getTimeSlot().getSlotStart() != null){ startSlot = new DateTime(time.getTimeSlot().getSlotStart(). getContent().toDate().getTime()); } //end of time slot if (time.getTimeSlot().getTimeSlotChoice() != null) if (time.getTimeSlot().getTimeSlotChoice().getSlotEnd() != null){ endSlot = new DateTime(time.getTimeSlot().getTimeSlotChoice(). getSlotEnd().toDate().getTime()); } else if (time.getTimeSlot().getTimeSlotChoice().getSlotDuration() != null){ endSlot = new DateTime(time.getTimeSlot().getTimeSlotChoice(). getSlotDuration().toLong()); } } long lTime = Math.max(slot.getStartMillis(), startPeriod.getMillis()); DateTime startTime = new DateTime(lTime); if (startSlot != null) if (timeOpers.beforeDayTime(startTime, startSlot)) timeOpers.setDayTime(startTime, startSlot); // sets startTime at the beginning of the required daytime window //duration long duration = time.getExecutionDuration().toLong(); return fitTimeSlot(startTime, slot.getEnd().getMillis() - startTime.getMillis(), duration, startSlot, endSlot, weekDays, inclDates, exclDates, startPeriod, endPeriod); } /** * Change given time to the start time of the next available slot. * * @param time - * time to be changed * @param duration - * duration of a period to be checked * @param start - * start time of a slot * @param end - * end time of a slot * @return new time */ protected DateTime nextSlot(DateTime time, long duration, DateTime start, DateTime end) { if (time == null) return null; if (start == null || end == null) { time = time.plusDays(1);//(Calendar.DAY_OF_MONTH, 1); return time; } //if within slot move to next day if (timeOpers.withinPeriodDayTime(time, duration, start, end)) time = time.plusDays(1); //(Calendar.DAY_OF_MONTH, 1); else //if not check when is start of the next slot if (timeOpers.beforeDayTime(start, end) && !timeOpers.beforeDayTime(time, start)) time = time.plusDays(1); //(Calendar.DAY_OF_MONTH, 1); //set time to start time of the slot timeOpers.setDayTime(time, start); return time; } public ReservationListNew getReservations() { return reservationList; } /** * Creates a list of time slots with usage of given resource type(including tasks * running without reservation) * Slots reflect time periods within which resource usage is constant * @param resourceUnit only two parameters of this object are used, type - which should be * the same type handled by this particular ReservationManager and resource id. Unit amount * is not used by this method, therefore this value may be set to 0 or null. * @param inExecution list of tasks which are currently running * @param startTime begin of the time period within which resource usage should be calculated * @param endTime end of the time period within which resource usage should be calculated * @return list of time slots with various resource usage * @throws NoSuchFieldException */ public ArrayList resourceUsageList(ResourceUnit resourceUnit, List> inExecution, DateTime startTime, DateTime endTime) throws NoSuchFieldException { String rmc = resourceUnit.getResourceId(); //Create a list of slots based on existing reservations that haven't been completed ArrayList v = new ArrayList(); for (int i=0; i < reservationList.size(); i++) { ReservationNew r =(ReservationNew)reservationList.get(i); if (r == null) continue; if (r.getStatus() != ReservationNew.Status.INITIAL && r.getStatus() != ReservationNew.Status.COMMITTED && r.getStatus() != ReservationNew.Status.ACTIVE) continue; if(!rmc.equals(r.getResourceName())) continue; TimeResourceAllocation orgSlot = r; if (orgSlot == null) continue; // sprawdzic jak to sie zachowa gdy rezerwacje przyjda dla ResUnit typu continous TimeResourceAllocation reserverdSlot = new TimeResourceAllocation( (ResourceDescription)orgSlot.getAllocatedResource().clone(), orgSlot.getStart(), orgSlot.getEnd()); // reserved slot ends before requested period starts if (reserverdSlot.getEnd().getMillis() <= startTime.getMillis()) continue; // reserved slot starts after requested period ends if (reserverdSlot.getStart().getMillis() >= endTime.getMillis()) break; //slot partially before requested period if (reserverdSlot.getStart().isBefore(startTime)){ reserverdSlot = new TimeResourceAllocation(reserverdSlot); reserverdSlot.setStart(startTime); } // first reserved slot starts after begin of the requested time period, which means that // resource between start time of requested time period and start time of first reservation // is not used. if (v.size() == 0) if (reserverdSlot.getStart().isAfter(startTime)) { ResourceUnit ru = (ResourceUnit)resourceUnit.clone(); ru.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(ru); v.add(new TimeResourceAllocation(rd, startTime, reserverdSlot.getStart())); } //slot partially after requested period TimeResourceAllocation oldSlot; if (reserverdSlot.getEnd().isAfter(endTime)) { oldSlot = reserverdSlot; reserverdSlot = new TimeResourceAllocation(oldSlot); reserverdSlot.setEnd(endTime); } v.add(reserverdSlot); } InExecuionList inExec = (InExecuionList)inExecution; ArrayList v2 = inExec.nonARTasksResourceUsageList(resourceUnit, startTime, endTime); ArrayList tempv = new ArrayList(); tempv.addAll(v); tempv.addAll(v2); TimeResourceAllocation[] traTable = new TimeResourceAllocation[tempv.size()]; int k = 0; for(TimeResourceAllocation task: tempv){ traTable[k] = task; k++; } MergeSort mergeSort = new MergeSort(); mergeSort.initSort(traTable, "getStartMillis", true); v.clear(); for(int i = 0; i < traTable.length; i++){ v.add(traTable[i]); } //if there is no resource usage in the requested period if (v.size() == 0) { ResourceUnit ru = (ResourceUnit) resourceUnit.clone(); ru.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(ru); v.add(new TimeResourceAllocation(rd, startTime, endTime)); } else { //last slot ends before end of the requested period TimeResourceAllocation slot = (TimeResourceAllocation)v.get(v.size() - 1); //last slot if (slot.getEnd().isBefore(endTime)) { ResourceUnit ru = (ResourceUnit) resourceUnit.clone(); ru.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(ru); v.add(new TimeResourceAllocation(rd, slot.getEnd(), endTime)); } } //Find gaps between slots and overlapping slots, and based on them generate additional slots int i = 0; while (i < v.size()) { TimeResourceAllocation previousSlot = (TimeResourceAllocation)v.get(i); TimeResourceAllocation slot = (TimeResourceAllocation)v.get(i); if (i + 1 < v.size()) slot = (TimeResourceAllocation)v.get(i + 1); else break; if(slot.getStart().compareTo(previousSlot.getEnd()) == 0) // one slot immediately after another i++; else if (slot.getStart().isAfter(previousSlot.getEnd())) { // there is a gap between two slots ResourceUnit resUsage = (ResourceUnit) resourceUnit.clone(); resUsage.reset(); ResourceStateDescription rd = new ResourceStateDescription(this.resourceProvider); rd.addResourceUnit(resUsage); TimeResourceAllocation slot1 = new TimeResourceAllocation(rd, previousSlot.getEnd(), slot.getStart()); v.add(++i, slot1); } else { // slots overlap (slot.getStartTime() < lastSlot.getEndTime()) DateTime start = previousSlot.getStart(); DateTime newStart = slot.getStart(); long lnewEnd = Math.min(previousSlot.getEnd().getMillis(),slot.getEnd().getMillis()); DateTime newEnd = new DateTime(lnewEnd); long lend = Math.max(previousSlot.getEnd().getMillis(),slot.getEnd().getMillis()); DateTime end = new DateTime(lend); ResourceDescription resUsage = (ResourceDescription) previousSlot.getAllocatedResource().clone(); TimeResourceAllocation slot1 = new TimeResourceAllocation(resUsage, start, newStart); resUsage = (ResourceDescription) previousSlot.getAllocatedResource().clone(); // mark processors which are unavailable in slot.resourceUnit as unavailable also in resUsage.resourceUnit object. // this should be a synonym for: previousSlot.getResourceUnit().getAmount()+slot.getResourceUnit().getAmount() { ResourceUnit unit = resUsage.getResourceUnit(ResourceParameterName.CPUCOUNT); if(unit instanceof List){ List peResUsage = (List) unit; ResourceUnit resUnit = slot.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); if(resUnit instanceof List){ List disResUnit = (List) resUnit; for(int a = 0; a < disResUnit.size(); a++){ Processor p = disResUnit.get(a); if(p.getStatus() == ResourceStatus.BUSY){ peResUsage.get(a).setStatus(ResourceStatus.BUSY); } else if(p.getStatus() == ResourceStatus.RESERVED){ peResUsage.get(a).setStatus(ResourceStatus.RESERVED); } } } else { log.warn("CHECK AND WERIFY IF THIS CODE IS CORRECT"); int cnt = Float.valueOf(resUnit.getAmount()).intValue(); for(int a = 0; a < peResUsage.size() && cnt > 0; a++){ if(peResUsage.get(a).getStatus() == ResourceStatus.FREE){ peResUsage.get(a).setStatus(ResourceStatus.BUSY); cnt--; } } } } else { ResourceUnit prevResUnit = previousSlot.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); ResourceUnit resUnit = slot.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT); ResourceUnit usedUnit = resUsage.getResourceUnit(ResourceParameterName.CPUCOUNT); usedUnit.setUsedAmount(prevResUnit.getUsedAmount() + resUnit.getUsedAmount()); } } TimeResourceAllocation slot2 = new TimeResourceAllocation(resUsage, newStart, newEnd); if (previousSlot.getEnd().isAfter(slot.getEnd())) { resUsage = (ResourceDescription) previousSlot.getAllocatedResource().clone(); } else { resUsage = (ResourceDescription) slot.getAllocatedResource().clone(); } TimeResourceAllocation slot3 = new TimeResourceAllocation(resUsage, newEnd, end); if (newEnd.compareTo(end) != 0){ int j=i+2; while ((j < v.size()) && (newEnd.isAfter(((TimeResourceAllocation)v.get(j)).getStart()))) j++; v.add(j, slot3); } v.remove(previousSlot); v.remove(slot); if (start.compareTo(newStart) != 0) { v.add(i++, slot1); v.add(i, slot2); } else {//equal start times of slots TimeResourceAllocation tra = null; float amount = -1; if (i > 0) { tra = (TimeResourceAllocation)v.get(i-1); amount = tra.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT).getUsedAmount(); } if (amount == slot2.getAllocatedResource().getResourceUnit(ResourceParameterName.CPUCOUNT).getUsedAmount()) { //two subsequent slots with equal resource usage tra.setEnd(slot2.getEnd()); //extend previous slot i--; } else v.add(i, slot2); }//equal start times of slots } } if (v.size() == 0){ if(log.isErrorEnabled()) log.error(getClass().getName()+" resourceUsage() - end, v.size = 0"); return null; } return v; } @Override public void init(Properties properties) throws ModuleException { // TODO Auto-generated method stub } @Override public void dispose() throws ModuleException { // TODO Auto-generated method stub } @Override public ModuleType getType() { return ModuleType.LOCAL_RESERVATION_MANAGER; } /*********************************/ public void cancelReservation(ReservationNew reservation, List> inExecution, List>> queues) throws ReservationException { // This method is not used in example configuration. } public ReservationNew commitReservation(ReservationNew initialReservation, List> inExecution, List>> queues, ResourceManagerInterface unitsManager) throws ReservationException { // this simple implementation changes status of the reservation // from INITIAL to COMMITED // list of reservations is managed by reservation manager List list = getReservations(); for(int i = 0; i < list.size(); i++){ ReservationNew r = list.get(i); // find correct reservation in reservations list if(initialReservation.getId().equals(r.getId())){ // change status to COMMITED r.setStatus(ReservationNew.Status.COMMITTED); // set job and task id on behalf which this reservation is // created. This is mostly for debugging purpose. r.setJobId(initialReservation.getJobId()); r.setTaskId(initialReservation.getTaskId()); // change status of initial reservation to COMMITED. // This allows grid plugin to notice, that reservation is // successfully committed. initialReservation.setStatus(ReservationNew.Status.COMMITTED); return initialReservation; } } return null; } public ReservationNew commitReservation(ReservationNew initialReservation, TimeResourceAllocation resourceUsage, List> inExecution, List>> queues, ResourceManagerInterface unitsManager) throws ReservationException { // This method is not used in example configuration. return null; } public List createReservation(ResourceUsage resourceUsage, List> inExecution, List>> queues, ResourceManagerInterface unitsManager) throws ReservationException { TimeResourceAllocation allocation = resourceUsage.get(0); ReservationNew reservation = getReservations().add(allocation, ReservationNew.Status.INITIAL); List list = new ArrayList(1); list.add(reservation); return list; } public ReservationNew createReservation( AbstractTimeRequirements timeRequirements, AbstractResourceRequirements resourceRequirements, List> inExecution, List>> queues, ResourceManagerInterface unitsManager) throws ReservationException { // This method is not used in example configuration. return null; } public Status getStatus(ReservationNew reservation) throws ReservationException { // This method is not used in example configuration. return null; } public ReservationNew modifyReservation(ReservationNew reservation, TimeResourceAllocation resourceUsage, List> inExecution, List>> queues, ResourceManagerInterface unitManager) throws ReservationException { // This method is not used in example configuration. return null; } public List getOffers(AbstractTimeRequirements timeReqs, AbstractResourceRequirements resReqs, List> inExecution, List>> queues, ResourceManagerInterface unitsManagerInterface) throws ReservationException { ResourceManager unitsManager = (ResourceManager) unitsManagerInterface; List usageList = null; int reqCpuCnt = 0; List list = new ArrayList(1); try { // get number of processors requested by the task reqCpuCnt = Double.valueOf(resReqs.getCpuCntRequest()).intValue(); // create unit for which resource usage will be created List processors = null ; try { processors = (List)unitsManager.getResourcesOfType(ResourceType.CPU); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } ProcessingElements pes = new ProcessingElements(processors.get(0).getParent().getName()); pes.addAll(processors); DateTime startTime = timeReqs.getStart(); DateTime endTime = timeReqs.getEnd(); // get resource usage usageList = resourceUsageList(pes, startTime, endTime); // check if resource can provide enough resources in requested time. // Prepare one, the earliest time period, which is suited exactly // for resource and time requirements. TimeResourceAllocation allocation = createSuitedAllocation(usageList, (TimeRequirements) timeReqs, (ResourceRequirements) resReqs); // allocation is null when it is impossible to provide enough resources // in requested time. Return empty offers list. if(allocation == null) return list; // add information about resource described by this allocation. // provider LocalSystem provider = new LocalSystem(pes.getResourceId(), null, null); // available resource units ResourceStateDescription resDesc = new ResourceStateDescription(provider); resDesc.addResourceUnit(new Processors(pes.getResourceId(), pes.size(), reqCpuCnt)); allocation.setAllocatedResource(resDesc); // prepare offer Offer offer = new Offer(); offer.setProvider(provider); offer.add(allocation); list.add(offer); } catch (NoSuchFieldException e) { e.printStackTrace(); return list; } return list; } private TimeResourceAllocation createSuitedAllocation(List usageList, TimeRequirements timeRequirements, ResourceRequirements resourceRequirements){ try { long reqDuration = timeRequirements.getEndMillis() - timeRequirements.getStartMillis(); long duration = reqDuration; int reqCpu = Double.valueOf(resourceRequirements.getCpuCntRequest()).intValue(); DateTime start = null; for(int i = 0; i < usageList.size() && duration > 0; i++){ TimeResourceAllocation allocation = usageList.get(i); ResourceUnit unit = allocation.getAllocatedResource(). getResourceUnit(ResourceParameterName.CPUCOUNT); if(unit.getFreeAmount() >= reqCpu){ duration = duration - (allocation.getEndMillis() - allocation.getStartMillis()); if(start == null) start = allocation.getStart(); } else { duration = reqDuration; start = null; } } if(duration > 0){ log.error("There is not enough free resources between " + timeRequirements.getStart() + " and " + timeRequirements.getEnd()); return null; } TimeResourceAllocation allocation = new TimeResourceAllocation(start, start.plus(reqDuration)); return allocation; } catch (NoSuchFieldException e) { e.printStackTrace(); } return null; } }