/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onebusaway.transit_data_federation.impl.otp; import java.util.Arrays; import org.onebusaway.transit_data_federation.impl.blocks.BlockSequence; import org.onebusaway.transit_data_federation.services.transit_graph.BlockTripEntry; /** * A trip sequence is a unique key used to differentiate on trip planning * itinerary from another. Typically, we use the {@link BlockTripEntry} as the * unique key segment. That way, if two itineraries are composed of the same * trip sequences we just keep the best one. * * That said, this is not exactly perfect. There are places for interlined * routes where the block-trip changes near a departure or arrival point. Thus, * the planner will often find two itineraries: * * 1) Where you board before the change. * * 2) Where you board after the change. * * Effectively, they are the same trip but they show up as unique because their * trip sequences are slightly different. * * You might be tempted to use the underlying block itself as the key, but this * would cause problems where the next best itinerary is the one where the * vehicle has done a lap and is back again. * * Instead, we use the underlying {@link BlockSequence} where available, since * this gets around this issue. * * @author bdferris * */ public class TripSequence { public static final TripSequence EMPTY = new TripSequence(new Object[] {}); private final Object[] sequence; public TripSequence(Object blockTrip) { sequence = new Object[] {blockTrip}; } private TripSequence(Object[] newSequence) { sequence = newSequence; } public TripSequence extend(Object blockTrip) { if (sequence.length > 0 && sequence[sequence.length - 1] == blockTrip) return this; Object[] newSequence = new Object[sequence.length + 1]; System.arraycopy(sequence, 0, newSequence, 0, sequence.length); newSequence[newSequence.length - 1] = blockTrip; return new TripSequence(newSequence); } @Override public int hashCode() { return Arrays.hashCode(sequence); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TripSequence other = (TripSequence) obj; return Arrays.equals(this.sequence, other.sequence); } }