HistoricalMap.java

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

  2. import java.util.ConcurrentModificationException;
  3. import java.util.LinkedHashMap;
  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-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  12.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  13.  * </p>
  14.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  15.  * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
  16.  * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
  17.  * @param <K> key type
  18.  * @param <V> value type
  19.  */
  20. public interface HistoricalMap<K, V> extends Map<K, V>
  21. {

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

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

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

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

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

  71. }