All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.profile.MultiProfileStateStore Maven / Gradle / Ivy

package org.opentripplanner.profile;

import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TObjectIntHashMap;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.opentripplanner.routing.vertextype.TransitStop;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

public class MultiProfileStateStore implements ProfileStateStore {
    private Multimap states = ArrayListMultimap.create();
    
    /** cache the minimum upper bounds for each stop, for performance */
    private TObjectIntMap minUpperBounds;
    
    @Override
    public boolean put(ProfileState ps) {
        if (ps.lowerBound < minUpperBounds.get(ps.stop)) {
            states.put(ps.stop, ps);
            
            if (ps.upperBound < minUpperBounds.get(ps.stop)) {
                minUpperBounds.put(ps.stop, ps.upperBound);
                
                // kick out old states
                for (Iterator it = states.get(ps.stop).iterator(); it.hasNext();) {
                    // need to use strictly-greater-than here, so states with no variation don't dominate themselves.
                    if (it.next().lowerBound > ps.upperBound) {
                        it.remove();
                    }
                }
            }
            
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public Collection get(TransitStop tstop) {
        return states.get(tstop);
    }

    @Override
    public Collection getAll() {
        return states.values();
    }
    
    @Override
    public int size() {
        return states.size();
    }
    
    /** merge similar states (states that have come from the same place on different patterns) */
    public void mergeStates() {
        Set touchedStopVertices = new HashSet(states.keySet());
        for (TransitStop tstop : touchedStopVertices) {
            Collection pss = states.get(tstop);
            
            // find states that have come from the same place
            Multimap foundStates = ArrayListMultimap.create();
            
            for (Iterator it = pss.iterator(); it.hasNext();) {
                ProfileState ps = it.next();
                foundStates.put(ps.previous, ps);
            }
            
            pss.clear();
            
            // merge them now
            for (Collection states : foundStates.asMap().values()) {                   
                if (states.size() == 1)
                    pss.addAll(states);
                else
                    pss.add(ProfileState.merge(states, true));
            }
        }
    }

    /**
     * initialize a multi profile state store for a new round based on the minimum upper bounds from a previous round.
     * Note that the min upper bound object is not copied, so the other profile state store can no longer be added to.
     */
    public MultiProfileStateStore (MultiProfileStateStore other) {
        minUpperBounds = other.minUpperBounds;
    }
    
    public MultiProfileStateStore () {
        minUpperBounds = new TObjectIntHashMap(5000, 0.75f, Integer.MAX_VALUE);
    }

    @Override
    public Collection keys() {
        return states.keySet();
    }

    @Override
    public boolean containsKey(TransitStop transitStop) {
        return states.containsKey(transitStop);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy