AbstractHistoricalCollection.java

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

  2. import java.util.Collection;
  3. import java.util.Collections;
  4. import java.util.Iterator;
  5. import java.util.LinkedHashSet;
  6. import java.util.Set;

  7. import org.djunits.value.vdouble.scalar.Time;
  8. import org.opentrafficsim.core.perception.AbstractHistorical;
  9. import org.opentrafficsim.core.perception.HistoryManager;
  10. import org.opentrafficsim.core.perception.collections.AbstractHistoricalCollection.EventCollection;

  11. /**
  12.  * Collection-valued historical state. The current collection is always maintained, and past states of the collection are
  13.  * obtained by applying the events between now and the requested time in reverse.<br>
  14.  * <br>
  15.  * This implementation is suitable for sets, as add and remove events to retrieve historical states are only created if indeed
  16.  * the underlying collection is changed. {@code Set} introduces no new methods relative to {@code Collection}.<br>
  17.  * <br>
  18.  * The {@code Iterator} returned by this class does not support the {@code remove()} method.
  19.  * <p>
  20.  * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  21.  * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  22.  * <p>
  23.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 jan. 2018 <br>
  24.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  25.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  26.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  27.  * @param <E> element type
  28.  * @param <C> collection type
  29.  */
  30. public abstract class AbstractHistoricalCollection<E, C extends Collection<E>>
  31.         extends AbstractHistorical<E, EventCollection<E, C>> implements HistoricalCollection<E>
  32. {

  33.     /** Current collection. */
  34.     private final C current;

  35.     /**
  36.      * Constructor.
  37.      * @param historyManager HistoryManager; history manager
  38.      * @param collection C; initial collection
  39.      */
  40.     protected AbstractHistoricalCollection(final HistoryManager historyManager, final C collection)
  41.     {
  42.         super(historyManager);
  43.         this.current = collection;
  44.     }

  45.     /**
  46.      * Returns the internal collection.
  47.      * @return C; internal collection
  48.      */
  49.     protected final C getCollection()
  50.     {
  51.         return this.current;
  52.     }

  53.     /**
  54.      * Fill collection with the current collection.
  55.      * @param collection C; collection to fill
  56.      * @return C; input collection filled
  57.      */
  58.     protected final C fill(final C collection)
  59.     {
  60.         collection.addAll(this.current);
  61.         return collection;
  62.     }

  63.     /**
  64.      * Fill collection with the collection at the given simulation time.
  65.      * @param time Time; time
  66.      * @param collection C; collection to fill
  67.      * @return C; input collection filled
  68.      */
  69.     protected final C fill(final Time time, final C collection)
  70.     {
  71.         // copy all current elements and decrement per event
  72.         collection.addAll(this.current);
  73.         for (EventCollection<E, C> event : getEvents(time))
  74.         {
  75.             event.restore(collection);
  76.         }
  77.         return collection;
  78.     }

  79.     // Altering Collection methods

  80.     /** {@inheritDoc} */
  81.     @Override
  82.     public boolean add(final E value)
  83.     {
  84.         boolean added = getCollection().add(value);
  85.         if (added)
  86.         {
  87.             addEvent(new AddEvent<>(now().si, value));
  88.         }
  89.         return added;
  90.     }

  91.     /** {@inheritDoc} */
  92.     @Override
  93.     public boolean addAll(final Collection<? extends E> c)
  94.     {
  95.         boolean changed = false;
  96.         for (E value : c)
  97.         {
  98.             changed |= add(value);
  99.         }
  100.         return changed;
  101.     }

  102.     /** {@inheritDoc} */
  103.     @Override
  104.     public void clear()
  105.     {
  106.         new LinkedHashSet<>(this.current).forEach(this::remove);
  107.     }

  108.     /** {@inheritDoc} */
  109.     @Override
  110.     @SuppressWarnings("unchecked")
  111.     public boolean remove(final Object value)
  112.     {
  113.         boolean removed = getCollection().remove(value);
  114.         if (removed)
  115.         {
  116.             addEvent(new RemoveEvent<>(now().si, (E) value)); // contains, so safe cast
  117.         }
  118.         return removed;
  119.     }

  120.     /** {@inheritDoc} */
  121.     @Override
  122.     public boolean removeAll(final Collection<?> c)
  123.     {
  124.         boolean changed = false;
  125.         for (Object value : c)
  126.         {
  127.             changed |= remove(value);
  128.         }
  129.         return changed;
  130.     }

  131.     /** {@inheritDoc} */
  132.     @Override
  133.     public boolean retainAll(final Collection<?> c)
  134.     {
  135.         boolean changed = false;
  136.         Set<E> values = new LinkedHashSet<>(this.current);
  137.         for (E value : values)
  138.         {
  139.             if (!c.contains(value))
  140.             {
  141.                 changed |= remove(value);
  142.             }
  143.         }
  144.         return changed;
  145.     }

  146.     // Non-altering Collection methods

  147.     /** {@inheritDoc} */
  148.     @Override
  149.     public int size()
  150.     {
  151.         return this.current.size();
  152.     }

  153.     /** {@inheritDoc} */
  154.     @Override
  155.     public boolean isEmpty()
  156.     {
  157.         return this.current.isEmpty();
  158.     }

  159.     /** {@inheritDoc} */
  160.     @Override
  161.     public boolean contains(final Object o)
  162.     {
  163.         return this.current.contains(o);
  164.     }

  165.     /** {@inheritDoc} */
  166.     @Override
  167.     public Iterator<E> iterator()
  168.     {
  169.         return Collections.unmodifiableCollection(this.current).iterator();
  170.     }

  171.     /** {@inheritDoc} */
  172.     @Override
  173.     public Object[] toArray()
  174.     {
  175.         return this.current.toArray();
  176.     }

  177.     /** {@inheritDoc} */
  178.     @Override
  179.     public <T> T[] toArray(final T[] a)
  180.     {
  181.         return this.current.toArray(a);
  182.     }

  183.     /** {@inheritDoc} */
  184.     @Override
  185.     public boolean containsAll(final Collection<?> c)
  186.     {
  187.         return this.current.containsAll(c);
  188.     }

  189.     // Events

  190.     /**
  191.      * Abstract super class for events that add or remove a value from the collection.
  192.      * <p>
  193.      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  194.      * <br>
  195.      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  196.      * <p>
  197.      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 jan. 2018 <br>
  198.      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  199.      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  200.      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  201.      * @param <E> element type
  202.      * @param <C> collection type
  203.      */
  204.     public abstract static class EventCollection<E, C extends Collection<E>> extends AbstractHistorical.EventValue<E>
  205.     {

  206.         /**
  207.          * Constructor.
  208.          * @param time double; time of event
  209.          * @param value E; value of event
  210.          */
  211.         public EventCollection(final double time, final E value)
  212.         {
  213.             super(time, value);
  214.         }

  215.         /**
  216.          * Restores the collection to the state of before the event.
  217.          * @param collection C; collection to restore
  218.          */
  219.         public abstract void restore(C collection);

  220.         /** {@inheritDoc} */
  221.         @Override
  222.         public String toString()
  223.         {
  224.             return "EventCollection []";
  225.         }

  226.     }

  227.     /**
  228.      * Event for adding value to the collection.
  229.      * <p>
  230.      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  231.      * <br>
  232.      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  233.      * <p>
  234.      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 jan. 2018 <br>
  235.      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  236.      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  237.      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  238.      * @param <E> element type
  239.      * @param <C> collection type
  240.      */
  241.     public static class AddEvent<E, C extends Collection<E>> extends EventCollection<E, C>
  242.     {

  243.         /**
  244.          * Constructor.
  245.          * @param time double; time of event
  246.          * @param value E; value of event
  247.          */
  248.         public AddEvent(final double time, final E value)
  249.         {
  250.             super(time, value);
  251.         }

  252.         /** {@inheritDoc} */
  253.         @Override
  254.         public void restore(final C collection)
  255.         {
  256.             collection.remove(getValue()); // events are only created upon effective addition, so we can remove it
  257.         }

  258.         /** {@inheritDoc} */
  259.         @Override
  260.         public String toString()
  261.         {
  262.             return "AddEvent []";
  263.         }

  264.     }

  265.     /**
  266.      * Event for removing value from the collection.
  267.      * <p>
  268.      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  269.      * <br>
  270.      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  271.      * <p>
  272.      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 1 jan. 2018 <br>
  273.      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  274.      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  275.      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  276.      * @param <E> element type
  277.      * @param <C> collection type
  278.      */
  279.     public static class RemoveEvent<E, C extends Collection<E>> extends EventCollection<E, C>
  280.     {

  281.         /**
  282.          * Constructor.
  283.          * @param time double; time of event
  284.          * @param value E; value of event
  285.          */
  286.         public RemoveEvent(final double time, final E value)
  287.         {
  288.             super(time, value);
  289.         }

  290.         /** {@inheritDoc} */
  291.         @Override
  292.         public void restore(final C collection)
  293.         {
  294.             collection.add(getValue()); // events are only created upon effective removal, so we can add it
  295.         }

  296.         /** {@inheritDoc} */
  297.         @Override
  298.         public String toString()
  299.         {
  300.             return "RemoveEvent []";
  301.         }

  302.     }

  303. }