[Bug #841] Automatic generic assignment limiting resources raises nullpointer exception

* Merge sort algorithm returned only the min gap for the first queue, but didn't explore all queues
* If a queue element can be applied to several queues, choose the queue with an earliest end date
* latestPossibleEnd was not correctly initialized

FEA : ItEr71S04BugFixing
This commit is contained in:
Diego Pino Garcia 2011-02-23 19:59:10 +01:00
parent 768cf47ee2
commit 12245f86ad
4 changed files with 64 additions and 28 deletions

View file

@ -139,15 +139,12 @@ public class InsertionRequirements {
Task task = element.getTask();
for (Dependency each : task.getDependenciesWithThisOrigin()) {
if (each.getType().modifiesDestinationEnd()) {
TaskElement destination = each.getDestination();
result = (result == null) ? destination.getIntraDayStartDate()
: IntraDayDate.min(result,
destination.getIntraDayStartDate());
}
TaskElement destination = each.getDestination();
result = (result == null) ? destination.getIntraDayStartDate()
: IntraDayDate.min(result,
destination.getIntraDayStartDate());
}
return (result != null) ? DateAndHour.from(result) : DateAndHour.from(new LocalDate(
element.getEarliestEndDateBecauseOfGantt()));
return (result != null) ? DateAndHour.from(result) : null;
}
public boolean isPotentiallyValid(Gap gap) {
@ -284,4 +281,4 @@ public class InsertionRequirements {
return earliestPossibleStart;
}
}
}

View file

@ -101,18 +101,27 @@ public class GapsMergeSort {
public static List<GapOnQueue> sort(
List<List<GapOnQueue>> orderedListsOfGaps) {
List<GapOnQueue> result = new ArrayList<GapOnQueue>();
if (orderedListsOfGaps.isEmpty()) {
return result;
}
if (orderedListsOfGaps.size() == 1) {
return orderedListsOfGaps.get(0);
}
List<GapOnQueue> result = new ArrayList<GapOnQueue>();
List<CurrentGap> currentGaps = CurrentGap.convert(iteratorsFor(orderedListsOfGaps));
CurrentGap min = null;
do {
min = Collections.min(currentGaps);
if (!min.hasFinished()) {
result.add(min.consume());
CurrentGap min = Collections.min(currentGaps);
while (!currentGaps.isEmpty() && !min.hasFinished()) {
result.add(min.consume());
if (min.hasFinished()) {
currentGaps.remove(min);
if (!currentGaps.isEmpty()) {
min = Collections.min(currentGaps);
}
}
} while (!min.hasFinished());
}
return result;
}

View file

@ -238,16 +238,20 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
for (ResourceAllocation<?> each: task.getAllResourceAllocations()) {
Hibernate.initialize(each);
}
for (Dependency each: task.getDependenciesWithThisOrigin()) {
Hibernate.initialize(each);
}
for (Dependency each: task.getDependenciesWithThisDestination()) {
Hibernate.initialize(each);
}
initializeDependencies(task);
initializeTaskSource(task.getTaskSource());
initializeRootOrder(task);
}
private void initializeDependencies(Task task) {
for (Dependency each: task.getDependenciesWithThisOrigin()) {
Hibernate.initialize(each.getDestination());
}
for (Dependency each: task.getDependenciesWithThisDestination()) {
Hibernate.initialize(each.getOrigin());
}
}
private boolean hasResourceAllocation(Task task) {
return !task.getLimitingResourceAllocations().isEmpty();
}
@ -688,8 +692,8 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
InsertionRequirements requirements, AllocationSpec allocation) {
LimitingResourceQueueElement element = requirements.getElement();
LimitingResourceQueue queue = queuesState.getQueueFor(element
.getResource());
List<LimitingResourceQueue> potentiallyValidQueues = getAssignableQueues(element);
LimitingResourceQueue queue = earliestQueue(potentiallyValidQueues);
List<LimitingResourceQueueElement> unscheduled = new ArrayList<LimitingResourceQueueElement>();
allocation = unscheduleElementsFor(queue, requirements, unscheduled);
@ -697,6 +701,32 @@ public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
return allocation;
}
/**
* Returns queue which last element is at a earliest date
*
* @param potentiallyValidQueues
* @return
*/
private LimitingResourceQueue earliestQueue(
List<LimitingResourceQueue> potentiallyValidQueues) {
LimitingResourceQueue result = null;
LocalDate latestDate = null;
for (LimitingResourceQueue each : potentiallyValidQueues) {
SortedSet<LimitingResourceQueueElement> elements = each
.getLimitingResourceQueueElements();
if (!elements.isEmpty()) {
LocalDate date = elements.last().getEndDate();
if (latestDate == null || date.isAfter(latestDate)) {
latestDate = date;
result = each;
}
}
}
return result;
}
private void checkAllocationIsAppropriative(boolean value) {
checkAllocationIsAppropriative = value;
}

View file

@ -195,10 +195,6 @@ public class QueuesState {
unassignedElements.remove(queueElement);
}
public LimitingResourceQueue getQueueFor(Resource resource) {
return queuesByResourceId.get(resource.getId());
}
public List<LimitingResourceQueue> getAssignableQueues(
LimitingResourceQueueElement element) {
final ResourceAllocation<?> resourceAllocation = element
@ -216,6 +212,10 @@ public class QueuesState {
throw new RuntimeException("unexpected type of: " + resourceAllocation);
}
private LimitingResourceQueue getQueueFor(Resource resource) {
return queuesByResourceId.get(resource.getId());
}
public InsertionRequirements getRequirementsFor(
LimitingResourceQueueElement element) {
List<LimitingResourceQueueDependency> dependenciesStart = new ArrayList<LimitingResourceQueueDependency>();