HistoricalMap.java

  1. package org.opentrafficsim.core.perception.collections;

  2. import java.util.ConcurrentModificationException;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import java.util.Objects;
  6. import java.util.function.BiFunction;

  7. import org.djunits.value.vdouble.scalar.Time;

  8. /**
  9.  * Interface for historical maps.
  10.  * <p>
  11.  * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  12.  * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  13.  * <p>
  14.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version 3 feb. 2018 <br>
  15.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  16.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  17.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  18.  * @param <K> key type
  19.  * @param <V> value type
  20.  */
  21. public interface HistoricalMap<K, V> extends Map<K, V>
  22. {

  23.     /**
  24.      * Returns the current map.
  25.      * @return Map; current map
  26.      */
  27.     Map<K, V> get();

  28.     /**
  29.      * Returns a past map.
  30.      * @param time Time; time to obtain the map at
  31.      * @return Map; past map
  32.      */
  33.     Map<K, V> get(Time time);

  34.     /** {@inheritDoc} */
  35.     @Override
  36.     default void replaceAll(final BiFunction<? super K, ? super V, ? extends V> function)
  37.     {
  38.         Objects.requireNonNull(function);
  39.         Map<K, V> puts = new HashMap<>();
  40.         for (Entry<K, V> entry : entrySet())
  41.         {
  42.             K k;
  43.             V v;
  44.             try
  45.             {
  46.                 k = entry.getKey();
  47.                 v = entry.getValue();
  48.             }
  49.             catch (IllegalStateException ise)
  50.             {
  51.                 // this usually means the entry is no longer in the map.
  52.                 throw new ConcurrentModificationException(ise);
  53.             }

  54.             // ise thrown from function is not a cme.
  55.             v = function.apply(k, v);

  56.             try
  57.             {
  58.                 // super uses entry.setValue(v) which is not supported, can't use put() due to concurrency
  59.                 puts.put(k, v);
  60.             }
  61.             catch (IllegalStateException ise)
  62.             {
  63.                 // this usually means the entry is no longer in the map.
  64.                 throw new ConcurrentModificationException(ise);
  65.             }
  66.         }
  67.         // second loop to perform the puts without concurrency
  68.         for (Entry<K, V> entry : puts.entrySet())
  69.         {
  70.             put(entry.getKey(), entry.getValue());
  71.         }
  72.     }

  73. }