LCOV - code coverage report
Current view: top level - builds/barbot/Cosmos/src/Simulator - EventsQueueSet.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 84 140 60.0 %
Date: 2021-06-16 15:43:28 Functions: 19 25 76.0 %

          Line data    Source code
       1             : /*******************************************************************************
       2             :  *                                                                             *
       3             :  * Cosmos:(C)oncept et (O)utils (S)tatistique pour les (Mo)deles               *
       4             :  * (S)tochastiques                                                             *
       5             :  *                                                                             *
       6             :  * Copyright (C) 2009-2012 LSV & LACL                                          *
       7             :  * Authors: BenoƮt Barbot & Paolo Ballarini & Hilal Djafri                     *
       8             :  * Website: http://www.lsv.ens-cachan.fr/Software/cosmos                       *
       9             :  *                                                                             *
      10             :  * This program is free software; you can redistribute it and/or modify        *
      11             :  * it under the terms of the GNU General Public License as published by        *
      12             :  * the Free Software Foundation; either version 3 of the License, or           *
      13             :  * (at your option) any later version.                                         *
      14             :  *                                                                             *
      15             :  * This program is distributed in the hope that it will be useful,             *
      16             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of              *
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
      18             :  * GNU General Public License for more details.                                *
      19             :  *                                                                             *
      20             :  * You should have received a copy of the GNU General Public License along     *
      21             :  * with this program; if not, write to the Free Software Foundation, Inc.,     *
      22             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                 *
      23             :  * file EventsQueueSet.cpp created by on 31/05/2016                            *
      24             :  *******************************************************************************
      25             :  */
      26             : 
      27             : #include <iostream>
      28             : #include <assert.h>
      29             : #include <algorithm>
      30             : #include <iomanip>
      31             : 
      32             : #include "Event.hpp"
      33             : #include "EventsQueueSet.hpp"
      34             : 
      35             : 
      36             : using namespace std;
      37             : 
      38             : /**
      39             :  *      Build an Event queue for the Petri net given as parameter.
      40             :  */
      41           4 : EventsQueueSet::EventsQueueSet(const std::vector<size_t> &t):
      42             :     evtHeapIndex(t.size()),
      43           4 :     evtTbl(t.size()){
      44           4 : }
      45             : 
      46             : /**
      47             :  * Clear the events queue. The resulting events queues does not contain any event.
      48             :  */
      49       39550 : void EventsQueueSet::reset() {
      50      132100 :     for(size_t it = 0; it< evtTbl.size(); ++it ){
      51       92550 :         evtHeapIndex[it].clear();
      52       92550 :         evtTbl[it].clear();
      53             :         }
      54       39550 :     evtHeap.clear();
      55             :     //Qsize = 0;
      56       39550 : }
      57             : 
      58             : /**
      59             :  * Copy of events queue
      60             :  */
      61           0 : EventsQueueSet::EventsQueueSet(const EventsQueueSet& orig) {
      62             :     
      63             :     //Qsize = orig.Qsize;
      64             :     
      65           0 :     evtTbl = orig.evtTbl;
      66           0 :     evtHeap = orig.evtHeap;
      67           0 :     evtHeapIndex = orig.evtHeapIndex;
      68             :     
      69             :     /*eq = orig.eq;
      70             :      TransTableSize = orig.TransTableSize;
      71             :      TransTable = orig.TransTable;*/
      72           0 : }
      73             : 
      74           8 : EventsQueueSet::~EventsQueueSet() {
      75           8 : }
      76             : 
      77             : /*
      78             :  *      Insert a new event in the events queue and update the tree.
      79             :  *  @param e an event of the Petri net.
      80             :  */
      81     1598915 : void EventsQueueSet::insert(const Event &e) {
      82             :     //assert(!isScheduled(e.transition, e.binding.id()));
      83             :     //cerr << "EQS insert"<< e << endl;
      84     1598915 :     Event& ep = evtTbl[e.transition][e.binding.id()];
      85     1598915 :     ep =e;
      86     1598915 :     evtHeapIndex[e.transition][e.binding.id()] = evtHeap.size();
      87     1598915 :     evtHeap.push_back( &ep );
      88             :     
      89     1598915 :     siftUp(evtHeap.size()-1);
      90     1598915 : }
      91             : 
      92             : /*
      93             :  *      Replace the time, priority,service of an event and update the tree.
      94             :  *  @param e an event of the Petri net.
      95             :  */
      96     5346000 : void EventsQueueSet::replace(const Event &e) {
      97             :     //assert(isScheduled(e.transition, e.binding.id()));
      98             :     //cerr << "EQS replace"<< e << ":" << evtHeap.size() << endl;
      99     5346000 :     long int k = evtHeapIndex[e.transition][e.binding.id()];
     100     5346000 :     evtTbl[e.transition][e.binding.id()] = e;
     101             :     
     102     5346000 :     siftUp(k);
     103     5346000 :     siftDown(k);
     104             :     //cerr << "EQS replace" << evtHeap.size() << endl;
     105     5346000 : }
     106             : 
     107     1533820 : void inline EventsQueueSet::remove(size_t tr,size_t i, size_t b){
     108             :     //cerr << "remove tr:"<< tr << "\t index: " << i << "binding: " <<b << "\t eventtable size : "<< evtHeap.size() << endl;
     109             :     
     110     1533820 :     if (i == evtHeap.size()-1) {
     111             :         //evtHeapIndex[tr].erase(b);
     112      114517 :         evtHeap.pop_back();
     113             :     } else {
     114     1419303 :         Event& lastEvent = *evtHeap.back();
     115     1419303 :         evtHeapIndex[lastEvent.transition][lastEvent.binding.id()] = i;
     116             :         //evtHeapIndex[tr].erase(b);
     117     1419303 :         evtHeap[i] = evtHeap.back();
     118     1419303 :         evtHeap.pop_back();
     119             :         
     120     1419303 :         siftDown(i);
     121     1419303 :         siftUp(i);
     122             :     }
     123     1533820 : }
     124             : 
     125             : /*
     126             :  *  Remove all event related to a transition.
     127             :  *  @param tr a transition of the Petri net.
     128             :  */
     129           0 : void EventsQueueSet::remove(size_t tr) {
     130             :     //cerr << "remove tr:"<< tr << "\t binding: ALL\t eventtable size : "<< evtHeap.size() << endl;
     131           0 :     for(const auto &bindmap: evtHeapIndex[tr]){
     132           0 :         auto i = bindmap.first;
     133           0 :         auto b = bindmap.second;
     134           0 :         remove(tr,i,b);
     135             :     }
     136           0 :     evtHeapIndex[tr].clear();
     137           0 : }
     138             : 
     139             : /*
     140             :  *      Remove an event and update the tree.
     141             :  *  @param tr a transition of the Petri net.
     142             :  *  @param b a binding of the Petri net.
     143             :  */
     144     1533820 : void EventsQueueSet::remove(size_t tr, size_t b) {
     145     1533820 :     long int i = -1;
     146     1533820 :     if(evtHeapIndex[tr].count(b)>0)i = evtHeapIndex[tr][b];
     147     1533820 :     evtTbl[tr].erase(b);
     148             :     //assert(i>=0);
     149     1533820 :     if(i>=0){
     150     1533820 :         remove(tr,i,b);
     151     1533820 :         evtHeapIndex[tr].erase(b);
     152             :     }
     153     1533820 : }
     154             : 
     155             : /**
     156             :  *  Pause an event, remove it from the tree
     157             :  *  @param t is the current time
     158             :  *  @param tr a transition of the Petri net.
     159             :  *  @param b a binding of the Petri net.
     160             :  */
     161           0 : void EventsQueueSet::pause(double t, size_t tr,size_t b){
     162             :     //assert(i>=0);
     163           0 :     if(evtHeapIndex[tr].count(b)>0){
     164           0 :         evtTbl[tr][b].time -= t;
     165           0 :         long int i = evtHeapIndex[tr][b];
     166           0 :         if(i>=0){
     167           0 :             if ((size_t)i == evtHeap.size()-1) {
     168           0 :                 evtHeapIndex[tr][b] = -1;
     169           0 :                 evtHeap.pop_back();
     170             :             } else {
     171           0 :                 Event& lastEvent = *evtHeap.back();
     172           0 :                 evtHeapIndex[lastEvent.transition][lastEvent.binding.id()] = i;
     173           0 :                 evtHeapIndex[tr][b] = -1 ;
     174           0 :                 evtHeap[i] = evtHeap.back();
     175           0 :                 evtHeap.pop_back();
     176             :                 
     177           0 :                 siftDown(i);
     178           0 :                 siftUp(i);
     179             :             }
     180             :         }
     181             :     }
     182           0 : }
     183             : 
     184             : /**
     185             :  * Check if an event can be restarted. If it is possible
     186             :  * restart it otherwise return false.
     187             :  *  @param t is the current time
     188             :  *  @param tr a transition of the Petri net.
     189             :  *  @param b a binding of the Petri net.
     190             :  */
     191     1311915 : bool EventsQueueSet::restart(double t, size_t tr,size_t b){
     192     1311915 :     if(evtTbl[tr].count(b) == 0)return false;
     193           0 :     Event& e = evtTbl[tr][b];
     194           0 :     if(e.time < 0.0)return false;
     195           0 :     e.time += t;
     196           0 :     evtHeapIndex[tr][b] = evtHeap.size();
     197           0 :     evtHeap.push_back(&e);
     198             :     
     199           0 :     siftUp(evtHeap.size()-1);
     200           0 :     return true;
     201             : }
     202             : 
     203    63567017 : const Event& EventsQueueSet::InPosition(size_t i)const {
     204             :     //cerr << i << "," << evtHeap.size() << endl;
     205             :     //assert(i < evtHeap.size());
     206    63567017 :     return *evtHeap[i];
     207             : }
     208             : 
     209             : 
     210     7316451 : const std::map<size_t, long int>& EventsQueueSet::getScheduledBinding(size_t tr)const {
     211     7316451 :     return evtHeapIndex[tr];
     212             : }
     213             : 
     214    37638668 : bool EventsQueueSet::isScheduled(size_t tr,size_t b)const {
     215    37638668 :     return (evtHeapIndex[tr].count(b) > 0);
     216             : }
     217             : 
     218    36227640 : Event& EventsQueueSet::getEvent(size_t tr, size_t b) {
     219    36227640 :     Event &e = evtTbl[tr][b];
     220    36227640 :     return e;
     221             : }
     222             : 
     223             : 
     224             : 
     225    15617544 : void EventsQueueSet::swapEvt(size_t i,size_t j){
     226             :     //assert((size_t)evtHeapIndex[evtHeap[j].first][evtHeap[j].second] ==j
     227             :     //     && (size_t)evtHeapIndex[evtHeap[i].first][evtHeap[i].second] == i);
     228    15617544 :     const Event& ei = *evtHeap[i];
     229    15617544 :     Event& ej = *evtHeap[j];
     230    15617544 :     evtHeapIndex[ej.transition][ej.binding.id()] = i;
     231    15617544 :     evtHeapIndex[ei.transition][ei.binding.id()] = j;
     232             :     
     233    15617544 :     evtHeap[j] = evtHeap[i];
     234    15617544 :     evtHeap[i] = &ej;
     235    15617544 : }
     236             : 
     237    10616810 : void EventsQueueSet::siftUp(size_t i) {
     238             :     size_t parentIndex;
     239             :     
     240    10616810 :     if (i != 0) {
     241     3402650 :         parentIndex = getParentIndex(i);
     242             :         
     243     3402650 :         if (InPosition(i).isPriorer(InPosition(parentIndex))){
     244     2252592 :             swapEvt(i, parentIndex);
     245     2252592 :             siftUp(parentIndex);
     246             :         }
     247             :     }
     248    10616810 : }
     249             : 
     250    20130255 : void EventsQueueSet::siftDown(size_t i) {
     251             :     size_t leftChildIndex, rightChildIndex, minIndex;
     252    20130255 :     leftChildIndex = getLeftChildIndex(i);
     253    20130255 :     rightChildIndex = getRightChildIndex(i);
     254    20130255 :     if (rightChildIndex >= evtHeap.size()) {
     255     8883175 :         if (leftChildIndex >= evtHeap.size())
     256     6292051 :             return;
     257             :         else
     258     2591124 :             minIndex = leftChildIndex;
     259             :     } else {
     260             :         
     261    11247080 :         if (InPosition(leftChildIndex).isPriorer(InPosition(rightChildIndex)))
     262     6464058 :             minIndex = leftChildIndex;
     263             :         else
     264     4783022 :             minIndex = rightChildIndex;
     265             :     }
     266             :     
     267    13838204 :     if (InPosition(minIndex).isPriorer(InPosition(i))) {
     268    13364952 :         swapEvt(minIndex,i);
     269    13364952 :         siftDown(minIndex);
     270             :     }
     271             :     
     272             :     
     273             : }
     274             : 
     275     6621149 : bool EventsQueueSet::isEmpty()const {
     276     6621149 :     return (evtHeap.size()==0);
     277             : }
     278             : 
     279           0 : void EventsQueueSet::printSedCmd(const std::vector<std::string> &trlabel, ostream& df)const {
     280           0 :     if(evtHeap.size()>0){
     281           0 :         df << "-e 's/\\$CF_" << trlabel[InPosition(0).transition] << "\\$/Red/g' ";
     282           0 :         for (unsigned int i = 1; i < evtHeap.size(); i++){
     283           0 :             df << "-e 's/\\$CF_" << trlabel[InPosition(i).transition] << "\\$/Blue/g' ";
     284             :         }
     285             :     }
     286           0 :     df << "-e 's/\\$CF_[^\\$]*\\$/Black/g' ";
     287           0 : }
     288             : 
     289             : /**
     290             :  *      Print the content of the queues in a human readable format.
     291             :  */
     292           0 : void EventsQueueSet::view(const std::vector<std::string> &trlabel)const {
     293           0 :     cerr << "********** EVENTS-QUEUE VIEW **********" << endl;
     294             :     
     295             :     //cerr << "Qsize:" << evtHeap.size() << endl;
     296             :     
     297           0 :     if (evtHeap.size() == 0)
     298           0 :         cerr << "EVENTS-QUEUE is empty!" << endl;
     299             :     else
     300           0 :         for (unsigned int i = 0; i < evtHeap.size(); i++){
     301           0 :             let e = InPosition(i);
     302             :             //cerr << "Equeue[" << i << "]:" << "( ";
     303           0 :             auto tr = trlabel[e.transition];
     304             :             //if(tr.DistTypeIndex == IMMEDIATE)cerr << "\033[1;33m";
     305           0 :             cerr << setw(15) << left << tr << ":";
     306             :             //cerr << "tr ID:" << setw(4)<< e.transition << " ";
     307           0 :             e.binding.print();
     308           0 :             cerr << ",\tt=" << e.time << ",\tp=" << e.priority << ",\tw=" << e.weight;
     309             :             //if(tr.DistTypeIndex == IMMEDIATE)cerr << "\033[0m";
     310           0 :             cerr << endl;
     311             :         }
     312           0 : }
     313             : 
     314           0 : size_t EventsQueueSet::getSize()const {
     315           0 :     return evtHeap.size();
     316          24 : }
     317             : 

Generated by: LCOV version 1.13