/** * A train line as a common set of stations with many departures * * @author ab */ package btools.memrouter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; final class ScheduledLine { String name; List<Integer> offsetMinutes = new ArrayList<Integer>(); TrainSchedule schedule; /** * get a list of departures relative to the start-time plus the individual * offsets according to the offset mask * * departures with the same wait-time are aggregated in one result element * with multiple 1-bits in the offset mask * * departures with different wait-times are returned as separate items * * @param id * the value to add to this set. * @return true if "id" already contained in this set. */ public List<ScheduledDeparture> getScheduledDepartures( int idx, long timeFrom, OffsetSet offsets ) { List<ScheduledDeparture> result = new ArrayList<ScheduledDeparture>(); long minutesFrom = ( timeFrom + 59999L ) / 60000L; long timeFromCorrection = minutesFrom * 60000L - timeFrom; if ( idx < 0 || idx >= offsetMinutes.size() - 1 ) return result; int offsetStart = offsetMinutes.get( idx ).intValue(); int offsetEnd = offsetMinutes.get( idx + 1 ).intValue(); Map<Integer, List<Integer>> waitOffsets = getDepartures( offsetStart, timeFrom + timeFromCorrection, offsets ); for ( Map.Entry<Integer, List<Integer>> e : waitOffsets.entrySet() ) { ScheduledDeparture depart = new ScheduledDeparture(); depart.waitTime = e.getKey().intValue() * 60000L + timeFromCorrection; depart.offsets = offsets.create( e.getValue() ); depart.rideTime = ( offsetEnd - offsetStart ) * 60000L; result.add( depart ); } return result; } private Map<Integer, List<Integer>> getDepartures( int offsetStart, long timeFrom, OffsetSet offsets ) { Map<Integer, List<Integer>> waitOffsets = new HashMap<Integer, List<Integer>>(); int size = offsets.size(); for ( int offset = 0;; ) { // skip to next offset bit while (offset < size && !offsets.contains( offset )) { offset++; } if ( offset >= size ) return waitOffsets; int toNext = schedule.getMinutesToNext( timeFrom + 60000L * ( offset - offsetStart ) ); if ( toNext < 0 ) return waitOffsets; int departOffset = offset + toNext; // whats the closest offset within the next toNext minutes int lastOffset = offset; while (toNext-- >= 0 && offset < size) { if ( offsets.contains( offset ) ) { lastOffset = offset; } offset++; } // if ( lastOffset == size - 1 ) // return waitOffsets; // todo? int waitTime = departOffset - lastOffset; // if we have that wait time in the list, just add the offset bit List<Integer> offsetList = waitOffsets.get( Integer.valueOf( waitTime ) ); if ( offsetList == null ) { offsetList = new ArrayList<Integer>(); waitOffsets.put( Integer.valueOf( waitTime ), offsetList ); } offsetList.add( Integer.valueOf( lastOffset ) ); } } }