예제 #1
0
 // See MinShouldMatchSumScorer for an explanation
 private static long cost(Collection<BulkScorer> scorers, int minShouldMatch) {
   final PriorityQueue<BulkScorer> pq =
       new PriorityQueue<BulkScorer>(scorers.size() - minShouldMatch + 1) {
         @Override
         protected boolean lessThan(BulkScorer a, BulkScorer b) {
           return a.cost() > b.cost();
         }
       };
   for (BulkScorer scorer : scorers) {
     pq.insertWithOverflow(scorer);
   }
   long cost = 0;
   for (BulkScorer scorer = pq.pop(); scorer != null; scorer = pq.pop()) {
     cost += scorer.cost();
   }
   return cost;
 }
예제 #2
0
  /**
   * Fetch upcoming vehicle departures from a stop. It goes though all patterns passing the stop for
   * the previous, current and next service date. It uses a priority queue to keep track of the next
   * departures. The queue is shared between all dates, as services from the previous service date
   * can visit the stop later than the current service date's services. This happens eg. with
   * sleeper trains.
   *
   * <p>TODO: Add frequency based trips
   *
   * @param stop Stop object to perform the search for
   * @param startTime Start time for the search. Seconds from UNIX epoch
   * @param timeRange Searches forward for timeRange seconds from startTime
   * @param numberOfDepartures Number of departures to fetch per pattern
   * @return
   */
  public List<StopTimesInPattern> stopTimesForStop(
      Stop stop, long startTime, int timeRange, int numberOfDepartures) {

    if (startTime == 0) {
      startTime = System.currentTimeMillis() / 1000;
    }
    List<StopTimesInPattern> ret = new ArrayList<>();
    TimetableSnapshot snapshot = null;
    if (graph.timetableSnapshotSource != null) {
      snapshot = graph.timetableSnapshotSource.getTimetableSnapshot();
    }
    ServiceDate[] serviceDates = {
      new ServiceDate().previous(), new ServiceDate(), new ServiceDate().next()
    };

    for (TripPattern pattern : patternsForStop.get(stop)) {

      // Use the Lucene PriorityQueue, which has a fixed size
      PriorityQueue<TripTimeShort> pq =
          new PriorityQueue<TripTimeShort>(numberOfDepartures) {
            @Override
            protected boolean lessThan(TripTimeShort tripTimeShort, TripTimeShort t1) {
              // Calculate exact timestamp
              return (tripTimeShort.serviceDay + tripTimeShort.realtimeDeparture)
                  > (t1.serviceDay + t1.realtimeDeparture);
            }
          };

      // Loop through all possible days
      for (ServiceDate serviceDate : serviceDates) {
        ServiceDay sd =
            new ServiceDay(graph, serviceDate, calendarService, pattern.route.getAgency().getId());
        Timetable tt;
        if (snapshot != null) {
          tt = snapshot.resolve(pattern, serviceDate);
        } else {
          tt = pattern.scheduledTimetable;
        }

        if (!tt.temporallyViable(sd, startTime, timeRange, true)) continue;

        int secondsSinceMidnight = sd.secondsSinceMidnight(startTime);
        int sidx = 0;
        for (Stop currStop : pattern.stopPattern.stops) {
          if (currStop == stop) {
            for (TripTimes t : tt.tripTimes) {
              if (!sd.serviceRunning(t.serviceCode)) continue;
              if (t.getDepartureTime(sidx) != -1
                  && t.getDepartureTime(sidx) >= secondsSinceMidnight) {
                pq.insertWithOverflow(new TripTimeShort(t, sidx, stop, sd));
              }
            }

            // TODO: This needs to be adapted after #1647 is merged
            for (FrequencyEntry freq : tt.frequencyEntries) {
              if (!sd.serviceRunning(freq.tripTimes.serviceCode)) continue;
              int departureTime = freq.nextDepartureTime(sidx, secondsSinceMidnight);
              if (departureTime == -1) continue;
              int lastDeparture =
                  freq.endTime
                      + freq.tripTimes.getArrivalTime(sidx)
                      - freq.tripTimes.getDepartureTime(0);
              int i = 0;
              while (departureTime <= lastDeparture && i < numberOfDepartures) {
                pq.insertWithOverflow(
                    new TripTimeShort(freq.materialize(sidx, departureTime, true), sidx, stop, sd));
                departureTime += freq.headway;
                i++;
              }
            }
          }
          sidx++;
        }
      }

      if (pq.size() != 0) {
        StopTimesInPattern stopTimes = new StopTimesInPattern(pattern);
        while (pq.size() != 0) {
          stopTimes.times.add(0, pq.pop());
        }
        ret.add(stopTimes);
      }
    }
    return ret;
  }