LCOV - code coverage report
Current view: top level - builds/barbot/Cosmos/src/Simulator - EventsQueue.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 80 131 61.1 %
Date: 2021-06-16 15:43:28 Functions: 16 21 76.2 %

          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: 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             :  *******************************************************************************
      24             :  */
      25             : 
      26             : #include "EventsQueue.hpp"
      27             : #include "Event.hpp"
      28             : #include <iostream>
      29             : #include <assert.h>
      30             : #include <algorithm>
      31             : #include <iomanip>
      32             : 
      33             : using namespace std;
      34             : 
      35             : /**
      36             :  *      Build an Event queue for the Petri net given as parameter.
      37             :  */
      38          22 : EventsQueue::EventsQueue(const std::vector<size_t> &t):evtTbl(t.size(),vector<Event>()){
      39          22 :     auto comp =0;
      40         436 :     for(size_t it = 0; it< t.size(); ++it ){
      41             :             //evtTbl.push_back(vector<Event>());
      42         414 :                 evtHeapIndex.push_back(vector<long int>(t[it],-1));
      43        1274 :                 for (size_t it2 = 0 ; it2< t[it]; ++it2) {
      44         860 :                         evtTbl[it].push_back(Event());
      45         860 :             comp++;
      46             :                 }
      47             :         }
      48          22 :     evtHeap.reserve(comp);
      49          22 : }
      50             : 
      51             : /**
      52             :  * Clear the events queue. The resulting events queues does not contain any event.
      53             :  */
      54      182552 : void EventsQueue::reset() {
      55     4052112 :         for(size_t it = 0; it< evtHeapIndex.size(); ++it )
      56     8635570 :                 for(size_t it2 = 0; it2< evtHeapIndex[it].size(); ++it2 ){
      57     4766010 :                         evtHeapIndex[it][it2]= -1;
      58     4766010 :                         evtTbl[it][it2].time = -1.0;
      59             :                 }
      60      182552 :         evtHeap.clear();
      61             :         //Qsize = 0;
      62      182552 : }
      63             : 
      64             : /**
      65             :  * Copy of events queue
      66             :  */
      67           0 : EventsQueue::EventsQueue(const EventsQueue& orig) {
      68             :     
      69             :     //Qsize = orig.Qsize;
      70             :         
      71           0 :         evtTbl = orig.evtTbl;
      72           0 :         evtHeap = orig.evtHeap;
      73           0 :         evtHeapIndex = orig.evtHeapIndex;
      74             :         
      75             :         /*eq = orig.eq;
      76             :          TransTableSize = orig.TransTableSize;
      77             :          TransTable = orig.TransTable;*/
      78           0 : }
      79             : 
      80          44 : EventsQueue::~EventsQueue() {
      81          44 : }
      82             : 
      83             : /*
      84             :  *      Insert a new event in the events queue and update the tree.
      85             :  *  @param e an event of the Petri net.
      86             :  */
      87    10570913 : void EventsQueue::insert(const Event &e) {
      88             :         //assert(!isScheduled(e.transition, e.binding.id()));
      89    10570913 :         evtTbl[e.transition][e.binding.id()] = e;
      90    10570913 :         evtHeapIndex[e.transition][e.binding.id()] = evtHeap.size();
      91    10570913 :         evtHeap.push_back(sizeSq(e.transition,e.binding.id()));
      92             :         
      93    10570913 :         siftUp(evtHeap.size()-1);
      94    10570913 : }
      95             : 
      96             : /*
      97             :  *      Replace the time, priority,service of an event and update the tree.
      98             :  *  @param e an event of the Petri net.
      99             :  */
     100    52000573 : void EventsQueue::replace(const Event &e) {
     101             :         //assert(isScheduled(e.transition, e.binding.id()));
     102    52000573 :         long int k = evtHeapIndex[e.transition][e.binding.id()];
     103    52000573 :         evtTbl[e.transition][e.binding.id()] = e;
     104             :         
     105    52000573 :         siftUp(k);
     106    52000573 :         siftDown(k);
     107    52000573 : }
     108             : 
     109             : /*
     110             :  *      Remove an event and update the tree.
     111             :  *  @param tr a transition of the Petri net.
     112             :  *  @param b a binding of the Petri net.
     113             :  */
     114    10210375 : void EventsQueue::remove(size_t tr, size_t b) {
     115    10210375 :         long int i = evtHeapIndex[tr][b];
     116    10210375 :         evtTbl[tr][b].time = -1.0;
     117             :         //assert(i>=0);
     118    10210375 :         if(i>=0){
     119    10210375 :                 if ((size_t)i == evtHeap.size()-1) {
     120      423312 :                         evtHeapIndex[tr][b] = -1;
     121      423312 :                         evtHeap.pop_back();
     122             :                 } else {
     123     9787063 :                         evtHeapIndex[evtHeap.back().tr][evtHeap.back().bid] = i;
     124     9787063 :                         evtHeapIndex[tr][b] = -1 ;
     125     9787063 :                         evtHeap[i] = evtHeap.back();
     126     9787063 :                         evtHeap.pop_back();
     127             :                         
     128     9787063 :                         siftDown(i);
     129     9787063 :                         siftUp(i);
     130             :                 }
     131             :         }
     132    10210375 : }
     133             : 
     134             : /**
     135             :  *  Pause an event, remove it from the tree
     136             :  *  @param t is the current time
     137             :  *  @param tr a transition of the Petri net.
     138             :  *  @param b a binding of the Petri net.
     139             :  */
     140           0 : void EventsQueue::pause(double t, size_t tr,size_t b){
     141           0 :         evtTbl[tr][b].time -= t;
     142           0 :         long int i = evtHeapIndex[tr][b];
     143             :         //assert(i>=0);
     144           0 :         if(i>=0){
     145           0 :                 if ((size_t)i == evtHeap.size()-1) {
     146           0 :                         evtHeapIndex[tr][b] = -1;
     147           0 :                         evtHeap.pop_back();
     148             :                 } else {
     149           0 :                         evtHeapIndex[evtHeap.back().tr][evtHeap.back().bid] = i;
     150           0 :                         evtHeapIndex[tr][b] = -1 ;
     151           0 :                         evtHeap[i] = evtHeap.back();
     152           0 :                         evtHeap.pop_back();
     153             :                         
     154           0 :                         siftDown(i);
     155           0 :                         siftUp(i);
     156             :                 }
     157             :         }
     158           0 : }
     159             : 
     160             : /**
     161             :  * Check if an event can be restarted. If it is possible 
     162             :  * restart it otherwise return false.
     163             :  *  @param t is the current time
     164             :  *  @param tr a transition of the Petri net.
     165             :  *  @param b a binding of the Petri net.
     166             :  */
     167     9629218 : bool EventsQueue::restart(double t, size_t tr,size_t b){
     168     9629218 :         if(evtTbl[tr][b].time < 0.0)return false;
     169           0 :         evtTbl[tr][b].time += t;
     170           0 :         evtHeapIndex[tr][b] = evtHeap.size();
     171           0 :         evtHeap.push_back(sizeSq(tr,b));
     172             :         
     173           0 :         siftUp(evtHeap.size()-1);
     174           0 :         return true;
     175             : }
     176             : 
     177             : 
     178   278189546 : const Event& EventsQueue::InPosition(size_t i)const {
     179             :         //assert(i < evtHeap.size());
     180   278189546 :     return evtTbl[evtHeap[i].tr][evtHeap[i].bid];
     181             : }
     182             : 
     183             : 
     184   168644228 : bool EventsQueue::isScheduled(size_t tr,size_t b)const {
     185   168644228 :         return (evtHeapIndex[tr][b] >= 0);
     186             : }
     187             : 
     188           0 : Event& EventsQueue::getEvent(size_t tr, size_t b) {
     189           0 :     Event &e = evtTbl[tr][b];
     190           0 :     return e;
     191             : }
     192             : 
     193             : 
     194             : 
     195    50284836 : void EventsQueue::swapEvt(size_t i,size_t j){
     196             :         //assert((size_t)evtHeapIndex[evtHeap[j].first][evtHeap[j].second] ==j
     197             :         //         && (size_t)evtHeapIndex[evtHeap[i].first][evtHeap[i].second] == i);
     198    50284836 :         evtHeapIndex[evtHeap[j].tr][evtHeap[j].bid] = i;
     199    50284836 :         evtHeapIndex[evtHeap[i].tr][evtHeap[i].bid] = j;
     200             :         
     201    50284836 :         sizeSq swappair = evtHeap[j];
     202    50284836 :         evtHeap[j] = evtHeap[i];
     203    50284836 :         evtHeap[i] = swappair;
     204    50284836 : }
     205             : 
     206             : 
     207    85426339 : void EventsQueue::siftUp(size_t i) {
     208             :     size_t parentIndex;
     209             :         
     210    85426339 :     if (i != 0) {
     211    31866301 :         parentIndex = getParentIndex(i);
     212             :                 
     213    31866301 :                 if (InPosition(i).isPriorer(InPosition(parentIndex))){
     214    13067790 :                         swapEvt(i, parentIndex);
     215    13067790 :                         siftUp(parentIndex);
     216             :                 }
     217             :         }
     218    85426339 : }
     219             : 
     220             : 
     221    99004682 : void EventsQueue::siftDown(size_t i) {
     222             :     size_t leftChildIndex, rightChildIndex, minIndex;
     223    99004682 :     leftChildIndex = getLeftChildIndex(i);
     224    99004682 :     rightChildIndex = getRightChildIndex(i);
     225    99004682 :     if (rightChildIndex >= evtHeap.size()) {
     226    72181446 :         if (leftChildIndex >= evtHeap.size())
     227    41461035 :             return;
     228             :         else
     229    30720411 :             minIndex = leftChildIndex;
     230             :     } else {
     231             :                 
     232    26823236 :         if (InPosition(leftChildIndex).isPriorer(InPosition(rightChildIndex)))
     233    15742532 :             minIndex = leftChildIndex;
     234             :         else
     235    11080704 :             minIndex = rightChildIndex;
     236             :     }
     237             :         
     238    57543647 :     if (InPosition(minIndex).isPriorer(InPosition(i))) {
     239    37217046 :                 swapEvt(minIndex,i);
     240    37217046 :         siftDown(minIndex);
     241             :     }
     242             :         
     243             :         
     244             : }
     245             : 
     246             : 
     247    46431025 : bool EventsQueue::isEmpty()const {
     248    46431025 :     return (evtHeap.size()==0);
     249             : }
     250             : 
     251             : 
     252           0 : void EventsQueue::printSedCmd(const std::vector<std::string> &trlabl,ostream& df)const {
     253           0 :     if(evtHeap.size()>0){
     254           0 :         df << "-e 's/\\$CF_" << trlabl[InPosition(0).transition] << "\\$/Red/g' ";
     255           0 :         for (unsigned int i = 1; i < evtHeap.size(); i++){
     256           0 :             df << "-e 's/\\$CF_" << trlabl[InPosition(i).transition] << "\\$/Lightblue/g' ";
     257             :         }
     258             :     }
     259           0 :     df << "-e 's/\\$CF_[^\\$]*\\$/Black/g' ";
     260           0 :     for(size_t i =0; i < trlabl.size(); i++ ){
     261           0 :         df << "-e 's/\\$ET_" << trlabl[i] << "\\$/";
     262           0 :         if(isScheduled( i , 0)){
     263           0 :             let ev = evtTbl[i][0];
     264           0 :             df << "(" << ev.time << ", " << ev.priority << ", " << ev.weight << ")";
     265             :         }
     266           0 :         df << "/g' ";
     267             :     }
     268           0 : }
     269             : 
     270             : /**
     271             :  *      Print the content of the queues in a human readable format.
     272             :  */
     273           0 : void EventsQueue::view(const std::vector<std::string> &trlabl)const {
     274           0 :     cerr << "********** EVENTS-QUEUE VIEW **********" << endl;
     275             :         
     276             :     //cerr << "Qsize:" << evtHeap.size() << endl;
     277             :         
     278           0 :     if (evtHeap.size() == 0)
     279           0 :         cerr << "EVENTS-QUEUE is empty!" << endl;
     280             :     else
     281           0 :         for (unsigned int i = 0; i < evtHeap.size(); i++){
     282           0 :                         Event e = InPosition(i);
     283             :             //cerr << "Equeue[" << i << "]:" << "( ";
     284           0 :             auto tr = trlabl[e.transition];
     285             :             //if(tr.DistTypeIndex == IMMEDIATE)cerr << "\033[1;33m";
     286           0 :             cerr << setw(15) << left << tr << "(" << e.transition << ") :";
     287             :             //cerr << "tr ID:" << setw(4)<< e.transition << " ";
     288           0 :                         e.binding.print();
     289           0 :                         cerr << ",\tt=" << e.time << ",\tp=" << e.priority << ",\tw=" << e.weight;
     290             :             //if(tr.DistTypeIndex == IMMEDIATE)cerr << "\033[0m";
     291           0 :                         cerr << endl;
     292             :                 }
     293          87 : }

Generated by: LCOV version 1.13