package graph; import java.util.ArrayDeque; import java.util.Deque; import java.util.TreeMap; import feature.StreetSegment; /** * Permanent label manager backed by exact-value ordered buckets. */ public class PermanentLabelBuckets extends AbstractLabelManager implements PermanentLabelManager { private TreeMap> buckets; /** * @param networkSize network size */ public PermanentLabelBuckets(final int networkSize) { super(networkSize); this.buckets = new TreeMap>(); } @Override public void adjustHeadValue(final StreetSegment segment) { if (segment == null) { return; } int headID = segment.getHead(); Label head = getLabel(headID); if (head == null || head.isPermanent()) { return; } double previous = head.getValue(); super.adjustHeadValue(segment); if (head.getValue() < previous) { addToBucket(headID, head.getValue()); } } @Override public Label getSmallestLabel() { while (!buckets.isEmpty()) { Double smallestKey = buckets.firstKey(); Deque ids = buckets.get(smallestKey); while (ids != null && !ids.isEmpty()) { int id = ids.removeFirst(); Label label = getLabel(id); if (label == null || label.isPermanent()) { continue; } if (Double.compare(label.getValue(), smallestKey.doubleValue()) == 0) { if (ids.isEmpty()) { buckets.remove(smallestKey); } return label; } } buckets.remove(smallestKey); } Label smallest = null; for (Label label : labels) { if (label == null || label.isPermanent()) { continue; } if (smallest == null || label.getValue() < smallest.getValue()) { smallest = label; } } return smallest; } @Override public void makePermanent(final int intersectionID) { Label label = getLabel(intersectionID); if (label != null) { label.makePermanent(); } } private void addToBucket(final int intersectionID, final double value) { Deque ids = buckets.get(value); if (ids == null) { ids = new ArrayDeque(); buckets.put(value, ids); } ids.addLast(intersectionID); } }