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

org.opentripplanner.routing.services.notes.StaticStreetNotesSource Maven / Gradle / Ivy

package org.opentripplanner.routing.services.notes;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.opentripplanner.common.model.T2;
import org.opentripplanner.model.StreetNote;
import org.opentripplanner.routing.edgetype.TemporaryPartialStreetEdge;
import org.opentripplanner.routing.graph.Edge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A notes source of static notes, usually created at graph building stage and not modified
 * thereafter.
 *
 * @author laurent
 */
public class StaticStreetNotesSource implements StreetNotesSource, Serializable {

  private static final long serialVersionUID = 1L;

  private static final Logger LOG = LoggerFactory.getLogger(StaticStreetNotesSource.class);

  /**
   * Notes for street edges. No need to synchronize access to the map as they will not be concurrent
   * write access (no notes for temporary edges, we use notes from parent).
   */
  private final SetMultimap notesForEdge = HashMultimap.create();

  /**
   * Set of unique matchers, kept during building phase, used for interning (lots of note/matchers
   * are identical).
   */
  private final transient Map, MatcherAndStreetNote> uniqueMatchers = new HashMap<>();

  StaticStreetNotesSource() {}

  /**
   * Return the set of notes applicable for this state / backedge pair.
   *
   * @return The set of notes or null if empty.
   */
  @Override
  public Set getNotes(Edge edge) {
    /* If the edge is temporary, we look for notes in it's parent edge. */
    if (edge instanceof TemporaryPartialStreetEdge) {
      edge = ((TemporaryPartialStreetEdge) edge).getParentEdge();
    }
    Set maas = notesForEdge.get(edge);
    if (maas == null || maas.isEmpty()) {
      return null;
    }
    return maas;
  }

  void addNote(Edge edge, StreetNote note, NoteMatcher matcher) {
    if (LOG.isDebugEnabled()) LOG.debug(
      "Adding note {} to {} with matcher {}",
      note,
      edge,
      matcher
    );
    notesForEdge.put(edge, buildMatcherAndAlert(matcher, note));
  }

  /**
   * Remove all notes attached to this edge. NOTE: this should only be called within a graph
   * building context (or unit testing).
   */
  void removeNotes(Edge edge) {
    if (LOG.isDebugEnabled()) LOG.debug("Removing notes for edge: {}", edge);
    notesForEdge.removeAll(edge);
  }

  /**
   * Create a MatcherAndAlert, interning it if the note and matcher pair is already created. Note:
   * we use the default Object.equals() for matchers, as they are mostly already singleton
   * instances.
   */
  private MatcherAndStreetNote buildMatcherAndAlert(NoteMatcher noteMatcher, StreetNote note) {
    T2 key = new T2<>(noteMatcher, note);
    MatcherAndStreetNote interned = uniqueMatchers.get(key);
    if (interned != null) {
      return interned;
    }
    MatcherAndStreetNote ret = new MatcherAndStreetNote(noteMatcher, note);
    uniqueMatchers.put(key, ret);
    return ret;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy