/** * Will allocate a row number to every extent in the list that may overlap the horizon. Row * numbers are assumed to begin at 0. This algorithm ensures that no temporal overlap occurs on * any given row and that the minimum number of rows are required. Extents whcih do not overlap * the horizon defined by horizonStart and horizonEnd will be given a row of -1. * * @param horizonStart Will ignore rows that cannot occur at or after this time. * @param horizonEnd Will ignore rows that cannot occur at or before this time. * @param extents A list of objects implementing the Extent interface whose rows are to be set * (thus may be changed) * @return A susbet of extents which intersected the time horizon, and for which rows have been * assigned. */ public static List allocateRows(int horizonStart, int horizonEnd, List extents) { List results = new ArrayList(); LinkedList source = new LinkedList(extents); Collections.sort(source, new ExtentComparator()); // Check the sort worked if (DEBUG_ON) { System.out.println("Debug version"); int max = 0; // Not safe for negative horizon start value. for (Iterator it = source.iterator(); it.hasNext(); ) { Extent extent = (Extent) it.next(); if (max > extent.getStart()) { System.out.println("Bad sort"); System.exit(-1); } max = extent.getStart(); } } int lastCount = extents.size(); int rowCount = 0; while (source.size() > 0) { boolean passedHorizon = false; int currentTime = horizonStart; Iterator it = source.iterator(); while (currentTime <= horizonEnd && it.hasNext()) { Extent extent = (Extent) it.next(); // If it is totally outside the horizon - ret rid of it and set row to NO_ROW if (extent.getEnd() < horizonStart || extent.getStart() > horizonEnd) { System.out.println("Removing element " + extent.toString() + " - outside horizon"); System.out.println( " start " + extent.getStart() + " end " + extent.getEnd() + " horizonStart " + horizonStart + " horizonEnd " + horizonEnd); extent.setRow(NO_ROW); it.remove(); continue; } // If it overlaps already placed extents, then just skip it if (extent.getStart() < currentTime && passedHorizon) // Also check to make sure it is not initial entry continue; // Otherwise, we will insert it in this row, and remove it from further consideration extent.setRow(rowCount); results.add(extent); it.remove(); // Update currentTime currentTime = extent.getEnd(); // Indicate we have inserted something and thus passed the Horizon passedHorizon = true; } rowCount++; if (DEBUG_ON) { if (source.size() >= lastCount) { System.out.println("Bug in the loop - should be converging but isn't"); System.exit(-1); } lastCount = source.size(); } } return results; }
public void add(Extent e) { e.setRow(n); latestEnd = e.getEnd(); }