LCOV - code coverage report
Current view: top level - src/utils/common - ValueTimeLine.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 30 30
Test Date: 2024-11-22 15:46:21 Functions: 100.0 % 8 8

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    ValueTimeLine.h
      15              : /// @author  Christian Roessel
      16              : /// @author  Daniel Krajzewicz
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // A list of time ranges with assigned values
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : #include <map>
      25              : #include <cassert>
      26              : #include <utility>
      27              : #include <utils/common/SUMOTime.h>
      28              : 
      29              : 
      30              : 
      31              : // ===========================================================================
      32              : // class definitions
      33              : // ===========================================================================
      34              : /**
      35              :  * @class ValueTimeLine
      36              :  *
      37              :  * A time line being a sorted container of non-overlapping time-ranges
      38              :  * with assigned values. The container is sorted by the first value of the
      39              :  * time-range while being filled. Every new inserted time range
      40              :  * may overwrite or split one or multiple earlier intervals.
      41              :  */
      42              : template<typename T>
      43          305 : class ValueTimeLine {
      44              : public:
      45              :     /// @brief Constructor
      46              :     ValueTimeLine() { }
      47              : 
      48              :     /// @brief Destructor
      49       481134 :     ~ValueTimeLine() { }
      50              : 
      51              :     /** @brief Adds a value for a time interval into the container.
      52              :      *
      53              :      * Make sure that begin >= 0 and begin < end.
      54              :      *
      55              :      * @param[in] begin the start time of the time range (inclusive)
      56              :      * @param[in] end the end time of the time range (exclusive)
      57              :      * @param[in] value the value to store
      58              :      */
      59       494328 :     void add(double begin, double end, T value) {
      60              :         assert(begin >= 0);
      61              :         assert(begin < end);
      62              :         // inserting strictly before the first or after the last interval (includes empty case)
      63       975010 :         if (myValues.upper_bound(begin) == myValues.end() ||
      64              :                 myValues.upper_bound(end) == myValues.begin()) {
      65        13646 :             myValues[begin] = std::make_pair(true, value);
      66        13646 :             myValues[end] = std::make_pair(false, value);
      67        13646 :             return;
      68              :         }
      69              :         // our end already has a value
      70              :         typename TimedValueMap::iterator endIt = myValues.find(end);
      71       480682 :         if (endIt != myValues.end()) {
      72              :             myValues.erase(myValues.upper_bound(begin), endIt);
      73       478435 :             myValues[begin] = std::make_pair(true, value);
      74       478435 :             return;
      75              :         }
      76              :         // we have at least one entry strictly before our end
      77              :         endIt = myValues.lower_bound(end);
      78              :         --endIt;
      79         2247 :         ValidValue oldEndValue = endIt->second;
      80              :         myValues.erase(myValues.upper_bound(begin), myValues.lower_bound(end));
      81         2247 :         myValues[begin] = std::make_pair(true, value);
      82         2247 :         myValues[end] = oldEndValue;
      83              :     }
      84              : 
      85              :     /** @brief Returns the value for the given time.
      86              :      *
      87              :      * There is no bounds checking applied! If there was no value
      88              :      *  set, the return value is undefined, the method may even segfault.
      89              :      *
      90              :      * @param[in] the time for which the value should be retrieved
      91              :      * @return the value for the time
      92              :      */
      93      4557275 :     T getValue(double time) const {
      94              :         assert(myValues.size() != 0);
      95              :         typename TimedValueMap::const_iterator it = myValues.upper_bound(time);
      96              :         assert(it != myValues.begin());
      97              :         --it;
      98      4557275 :         return it->second.second;
      99              :     }
     100              : 
     101              :     /** @brief Returns whether a value for the given time is known.
     102              :      *
     103              :      * This method implements the bounds checking. It returns true
     104              :      *  if and only if an explicit value was set for the given time
     105              :      *  using add. Default values stemming from fillGaps are not
     106              :      *  considered valid.
     107              :      *
     108              :      * @param[in] the time for which the value should be retrieved
     109              :      * @return whether a valid value was set
     110              :      */
     111      5161874 :     bool describesTime(double time) const {
     112              :         typename TimedValueMap::const_iterator afterIt = myValues.upper_bound(time);
     113      5161874 :         if (afterIt == myValues.begin()) {
     114              :             return false;
     115              :         }
     116              :         --afterIt;
     117      4338457 :         return afterIt->second.first;
     118              :     }
     119              : 
     120              :     /** @brief Returns the time point at which the value changes.
     121              :      *
     122              :      * If the two input parameters lie in two consecutive time
     123              :      *  intervals, this method returns the point at which the
     124              :      *  interval changes. In any other case -1 is returned.
     125              :      *
     126              :      * @param[in] low the time in the first interval
     127              :      * @param[in] high the time in the second interval
     128              :      * @return the split point
     129              :      */
     130           68 :     double getSplitTime(double low, double high) const {
     131              :         typename TimedValueMap::const_iterator afterLow = myValues.upper_bound(low);
     132              :         typename TimedValueMap::const_iterator afterHigh = myValues.upper_bound(high);
     133              :         --afterHigh;
     134           68 :         if (afterLow == afterHigh) {
     135           18 :             return afterLow->first;
     136              :         }
     137              :         return -1;
     138              :     }
     139              : 
     140              :     /** @brief Sets a default value for all unset intervals.
     141              :      *
     142              :      * @param[in] value the value to store
     143              :      * @param[in] extendOverBoundaries whether the first/last value should be valid for later / earlier times as well
     144              :      */
     145         3672 :     void fillGaps(T value, bool extendOverBoundaries = false) {
     146        12905 :         for (typename TimedValueMap::iterator it = myValues.begin(); it != myValues.end(); ++it) {
     147         9233 :             if (!it->second.first) {
     148         3816 :                 it->second.second = value;
     149              :             }
     150              :         }
     151         3672 :         if (extendOverBoundaries && !myValues.empty()) {
     152              :             typename TimedValueMap::iterator it = --myValues.end();
     153         2892 :             if (!it->second.first) {
     154              :                 myValues.erase(it, myValues.end());
     155              :             }
     156         2892 :             value = myValues.begin()->second.second;
     157              :         }
     158         3672 :         myValues[-1] = std::make_pair(false, value);
     159         3672 :     }
     160              : 
     161              : private:
     162              :     /// @brief Value of time line, indicating validity.
     163              :     typedef std::pair<bool, T> ValidValue;
     164              : 
     165              :     /// @brief Sorted map from start of intervals to values.
     166              :     typedef std::map<double, ValidValue> TimedValueMap;
     167              : 
     168              :     /// @brief The list of time periods (with values)
     169              :     TimedValueMap myValues;
     170              : 
     171              : };
        

Generated by: LCOV version 2.0-1