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://tudelft.nl/staff/p.knoppers-1">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 Map; current map
  25.      */
  26.     Map<K, V> get();

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

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

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

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

  72. }