$treeview $search $mathjax
SEvMgr Logo  1.00.2
$projectbrief
$projectbrief
$searchbox

EventQueue.cpp

Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 // StdAir
00007 #include <stdair/stdair_exceptions.hpp>
00008 #include <stdair/basic/BasConst_Event.hpp>
00009 #include <stdair/bom/EventStruct.hpp>
00010 #include <stdair/service/Logger.hpp>
00011 // SEvMgr
00012 #include <sevmgr/basic/BasConst_EventQueueManager.hpp>
00013 #include <sevmgr/bom/EventQueue.hpp>
00014 
00015 namespace SEVMGR {
00016   
00017   // //////////////////////////////////////////////////////////////////////
00018   EventQueue::EventQueue()
00019     : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
00020       _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
00021                        stdair::DEFAULT_PROGRESS_STATUS) {
00022   }
00023   
00024   // //////////////////////////////////////////////////////////////////////
00025   EventQueue::EventQueue (const Key_T& iKey)
00026     : _key (iKey), _parent (NULL),
00027       _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
00028                        stdair::DEFAULT_PROGRESS_STATUS) {
00029   }
00030   
00031   // //////////////////////////////////////////////////////////////////////
00032   EventQueue::EventQueue (const EventQueue& iEventQueue)
00033     : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
00034       _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
00035                        stdair::DEFAULT_PROGRESS_STATUS) {
00036     assert (false);
00037   }
00038   
00039   // //////////////////////////////////////////////////////////////////////
00040   EventQueue::~EventQueue() {
00041     _eventList.clear();
00042   }
00043   
00044   // //////////////////////////////////////////////////////////////////////
00045   std::string EventQueue::toString() const {
00046     std::ostringstream oStr;
00047     oStr << "(" << _eventList.size() << ") "
00048          << _progressStatus.getCurrentNb() << "/{"
00049          << _progressStatus.getExpectedNb() << ","
00050          << _progressStatus.getActualNb() << "}";
00051     return oStr.str();
00052   }
00053 
00054   // //////////////////////////////////////////////////////////////////////
00055   std::string EventQueue::display() const {
00056     std::ostringstream oStr;
00057 
00058     oStr << toString();
00059 
00060     return oStr.str();
00061   } 
00062 
00063   // //////////////////////////////////////////////////////////////////////
00064   std::string EventQueue::list () const {
00065     std::ostringstream oStr;  
00066     oStr << describeKey () << std::endl;
00067     oStr << toString() << std::endl;
00068 
00069     // Browse the events
00070     for (stdair::EventList_T::const_iterator itEvent = _eventList.begin();
00071          itEvent != _eventList.end(); ++itEvent) {
00072       const stdair::EventStruct& lEvent = itEvent->second;
00073  
00074       oStr << lEvent.describe();
00075     }
00076     
00077     return oStr.str();
00078   } 
00079 
00080   // //////////////////////////////////////////////////////////////////////
00081   std::string EventQueue::
00082   list (const stdair::EventType::EN_EventType& iType) const {  
00083       std::ostringstream oStr;  
00084       oStr << describeKey () << std::endl; 
00085       oStr << toString() << std::endl;
00086       oStr << "List " << stdair::EventType::getLabel(iType) 
00087            << " events:" << std::endl;
00088       
00089       // Browse the events
00090       for (stdair::EventList_T::const_iterator itEvent = _eventList.begin();
00091            itEvent != _eventList.end(); ++itEvent) {
00092         const stdair::EventStruct& lEvent = itEvent->second;
00093  
00094         if (lEvent.getEventType() == iType) {  
00095           oStr << lEvent.describe();
00096         }
00097       } 
00098       return oStr.str();
00099   }
00100 
00101   // //////////////////////////////////////////////////////////////////////
00102   stdair::Count_T EventQueue::getQueueSize () const {
00103     return _eventList.size();
00104   }
00105   
00106   // //////////////////////////////////////////////////////////////////////
00107   bool EventQueue::isQueueEmpty () const {
00108     return _eventList.empty();
00109   }
00110   
00111   // //////////////////////////////////////////////////////////////////////
00112   bool EventQueue::isQueueDone () const {
00113     const bool isQueueEmpty = _eventList.empty();
00114     return isQueueEmpty;
00115   }
00116 
00117   // //////////////////////////////////////////////////////////////////////
00118   void EventQueue::reset () {
00119     // Reset only the current number of events, not the expected one
00120     _progressStatus.reset();
00121     
00122     // Empty the list of events
00123     _eventList.clear();
00124 
00125     // Reset the progress statuses for all the event types
00126     for (ProgressStatusMap_T::iterator itProgressStatus =
00127            _progressStatusMap.begin();
00128          itProgressStatus != _progressStatusMap.end(); ++itProgressStatus) {
00129       stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
00130       lProgressStatus.reset();
00131     }
00132   }
00133 
00134   // //////////////////////////////////////////////////////////////////////
00135   bool EventQueue::
00136   hasProgressStatus (const stdair::EventType::EN_EventType& iType) const {
00137 
00138     bool hasProgressStatus = true;
00139 
00140     // Retrieve the ProgressStatus structure corresponding to the
00141     // given event type
00142     ProgressStatusMap_T::const_iterator itProgressStatus =
00143       _progressStatusMap.find (iType);
00144     if (itProgressStatus == _progressStatusMap.end()) {
00145       //
00146       STDAIR_LOG_DEBUG ("No ProgressStatus structure can be retrieved in the "
00147                         << "EventQueue: " << display());
00148 
00149       hasProgressStatus = false;
00150     }
00151     
00152     return hasProgressStatus;
00153   }
00154   
00155   // //////////////////////////////////////////////////////////////////////
00156   const stdair::Count_T& EventQueue::
00157   getCurrentNbOfEvents (const stdair::EventType::EN_EventType& iType) const {
00158 
00159     // Retrieve the ProgressStatus structure corresponding to the
00160     // given event type
00161     ProgressStatusMap_T::const_iterator itProgressStatus =
00162       _progressStatusMap.find (iType);
00163     if (itProgressStatus == _progressStatusMap.end()) {
00164       //
00165       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00166                         << "EventQueue: " << display());
00167       assert (false);
00168     }
00169     
00170     const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
00171     return lProgressStatus.getCurrentNb();
00172   }
00173 
00174   // //////////////////////////////////////////////////////////////////////
00175   const stdair::Count_T& EventQueue::
00176   getExpectedTotalNbOfEvents (const stdair::EventType::EN_EventType& iType) const {
00177 
00178     // Retrieve the ProgressStatus structure corresponding to the
00179     // given event type
00180     ProgressStatusMap_T::const_iterator itProgressStatus =
00181       _progressStatusMap.find (iType);
00182     if (itProgressStatus == _progressStatusMap.end()) {
00183       std::ostringstream oStr;
00184       oStr << "No ProgressStatus structure can be retrieved in the EventQueue '"
00185            << display() << "'. The EventQueue should be initialised, e.g., by "
00186            << "calling a buildSampleBom() method.";
00187       //
00188       STDAIR_LOG_ERROR (oStr.str());
00189       throw EventQueueException (oStr.str());
00190     }
00191     
00192     const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
00193     return lProgressStatus.getExpectedNb();
00194   }
00195 
00196   // //////////////////////////////////////////////////////////////////////
00197   const stdair::Count_T& EventQueue::
00198   getActualTotalNbOfEvents (const stdair::EventType::EN_EventType& iType) const {
00199 
00200     // Retrieve the ProgressStatus structure corresponding to the
00201     // given event type
00202     ProgressStatusMap_T::const_iterator itProgressStatus =
00203       _progressStatusMap.find (iType);
00204     if (itProgressStatus == _progressStatusMap.end()) {
00205       //
00206       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00207                         << "EventQueue: " << display());
00208       assert (false);
00209     }
00210     
00211     const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
00212     return lProgressStatus.getActualNb();
00213   }
00214 
00215   // //////////////////////////////////////////////////////////////////////
00216   void EventQueue::updateStatus (const stdair::EventType::EN_EventType& iType,
00217                                  const stdair::ProgressStatus& iProgressStatus) {
00218 
00219     // Retrieve, if existing, the ProgressStatus structure
00220     // corresponding to the given event type
00221     ProgressStatusMap_T::iterator itProgressStatus =
00222       _progressStatusMap.find (iType);
00223     if (itProgressStatus == _progressStatusMap.end()) {
00224       const bool hasInsertBeenSuccessful =
00225         _progressStatusMap.insert (ProgressStatusMap_T::
00226                                    value_type (iType, iProgressStatus)).second;
00227       
00228       if (hasInsertBeenSuccessful == false) {
00229         STDAIR_LOG_ERROR ("No progress_status can be inserted "
00230                           << "for the following event type: "
00231                           << stdair::EventType::getLabel(iType)
00232                           << ". EventQueue: " << toString());
00233         throw stdair::EventException ("No progress_status can be inserted for the "
00234                                       "following event type: "
00235                                       + stdair::EventType::getLabel(iType)
00236                                       + ". EventQueue: " + toString());
00237       }
00238 
00239       return;
00240     }
00241     
00242     stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
00243 
00244     // Update the progress status
00245     const stdair::Count_T& lCurrentNb = iProgressStatus.getCurrentNb();
00246     lProgressStatus.setCurrentNb (lCurrentNb);
00247 
00248     const stdair::Count_T& lExpectedNb = iProgressStatus.getExpectedNb();
00249     lProgressStatus.setExpectedNb(lProgressStatus.getExpectedNb() + lExpectedNb);
00250 
00251     const stdair::Count_T& lActualNb = iProgressStatus.getActualNb();
00252     lProgressStatus.setActualNb (lProgressStatus.getActualNb() + lActualNb);
00253   }
00254 
00255   // //////////////////////////////////////////////////////////////////////
00256   void EventQueue::
00257   addStatus (const stdair::EventType::EN_EventType& iType,
00258              const stdair::NbOfEvents_T& iExpectedTotalNbOfEvents) {
00259 
00260     // Initialise the progress status object
00261     const stdair::Count_T lExpectedTotalNbOfEventsInt =
00262       static_cast<const stdair::Count_T> (std::floor (iExpectedTotalNbOfEvents));
00263     const stdair::ProgressStatus lProgressStatus (lExpectedTotalNbOfEventsInt);
00264       
00265     // Update the progress status for the given event type
00266     updateStatus (iType, lProgressStatus);
00267     
00268     // Update the overall progress status
00269     const stdair::Count_T lExpectedNb = 
00270       static_cast<const stdair::Count_T> (_progressStatus.getExpectedNb()
00271                                   + iExpectedTotalNbOfEvents);
00272     _progressStatus.setExpectedNb (lExpectedNb);
00273 
00274     const stdair::Count_T lActualNb = 
00275       static_cast<const stdair::Count_T> (_progressStatus.getActualNb()
00276                                   + iExpectedTotalNbOfEvents);
00277     _progressStatus.setActualNb (lActualNb);
00278 
00279   }
00280 
00281   // //////////////////////////////////////////////////////////////////////
00282   void EventQueue::updateStatus (const stdair::EventType::EN_EventType& iType,
00283                                  const stdair::NbOfEvents_T& iActualNbOfEvents) { 
00284 
00285     // Initialise the progress status object for the type key
00286     const stdair::Count_T lActualNbOfEventsInt =
00287       static_cast<const stdair::Count_T> (std::floor (iActualNbOfEvents));
00288       
00289     // Update the progress status for the corresponding content type key
00290     ProgressStatusMap_T::iterator itProgressStatus =
00291       _progressStatusMap.find (iType);
00292     if (itProgressStatus != _progressStatusMap.end()) {
00293 
00294       //
00295       stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
00296 
00297       // Update the overall progress status
00298       const stdair::Count_T& lActualEventTypeNb = lProgressStatus.getActualNb();
00299       const stdair::Count_T lActualEventTypeNbInt =
00300         static_cast<const stdair::Count_T> (std::floor (lActualEventTypeNb));
00301       const stdair::Count_T& lActualTotalNb = _progressStatus.getActualNb();
00302       const stdair::Count_T lActualDeltaNb = lActualNbOfEventsInt - lActualEventTypeNbInt;
00303       _progressStatus.setActualNb (lActualTotalNb + lActualDeltaNb);
00304 
00305       // Update the progress status for the corresponding type key
00306       lProgressStatus.setActualNb (lActualNbOfEventsInt); 
00307     }  
00308   }
00309 
00310   // //////////////////////////////////////////////////////////////////////
00311   void EventQueue::setStatus (const stdair::EventType::EN_EventType& iType,
00312                               const stdair::ProgressStatus& iProgressStatus) {
00313 
00314     // Retrieve the ProgressStatus structure corresponding to the
00315     // given event type
00316     ProgressStatusMap_T::iterator itProgressStatus =
00317       _progressStatusMap.find (iType);
00318     // assert (itProgressStatus != _progressStatusMap.end());
00319     if (itProgressStatus != _progressStatusMap.end()) {
00320       // Update the ProgressStatus structure
00321       itProgressStatus->second = iProgressStatus;
00322     }
00323   }
00324 
00325   // //////////////////////////////////////////////////////////////////////
00326   const stdair::ProgressStatus& EventQueue::
00327   getStatus (const stdair::EventType::EN_EventType& iType) const {
00328 
00329     // Retrieve the ProgressStatus structure corresponding to the
00330     // given event type
00331     ProgressStatusMap_T::const_iterator itProgressStatus =
00332       _progressStatusMap.find (iType);   
00333     if (itProgressStatus == _progressStatusMap.end()) {
00334       std::ostringstream oStr;
00335       oStr << "No ProgressStatus structure can be retrieved in the EventQueue '" 
00336            << display() << "' for the following event type: " 
00337            << stdair::EventType::getLabel(iType) << ".";
00338       //
00339       STDAIR_LOG_ERROR (oStr.str());
00340       throw EventQueueException (oStr.str());
00341     }
00342     assert(itProgressStatus != _progressStatusMap.end());
00343     
00344     const stdair::ProgressStatus& oProgressStatus = itProgressStatus->second;
00345     return oProgressStatus;
00346   }
00347 
00348   // //////////////////////////////////////////////////////////////////////
00349   stdair::ProgressPercentage_T EventQueue::
00350   calculateProgress (const stdair::EventType::EN_EventType& iType) const {
00351 
00352     // Retrieve the ProgressStatus structure corresponding to the
00353     // given event type
00354     ProgressStatusMap_T::const_iterator itProgressStatus =
00355       _progressStatusMap.find (iType);
00356     if (itProgressStatus == _progressStatusMap.end()) {
00357       //
00358       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00359                         << "EventQueue: " << display());
00360       assert (false);
00361     }
00362     
00363     const stdair::ProgressStatus& lProgressStatus = itProgressStatus->second;
00364     return lProgressStatus.progress();
00365   }
00366 
00367   // //////////////////////////////////////////////////////////////////////
00368   stdair::ProgressStatusSet EventQueue::popEvent (stdair::EventStruct& ioEventStruct) {
00369 
00370     if (_eventList.empty() == true) {  
00371       std::ostringstream oStr;
00372       oStr << "The event queue '" << describeKey() << "' is empty. "
00373            << "No event can be popped.";
00374       //
00375       STDAIR_LOG_ERROR (oStr.str());
00376       throw EventQueueException (oStr.str());
00377     }
00378 
00382     // Get an iterator on the first event (sorted by date-time stamps)
00383     stdair::EventList_T::iterator itEvent = _eventList.begin();
00384 
00391     ioEventStruct = itEvent->second;
00392     // Retrieve the event type
00393     const stdair::EventType::EN_EventType& lEventType = ioEventStruct.getEventType();
00394     stdair::ProgressStatusSet oProgressStatusSet (lEventType);
00395   
00396     // Update the (current number part of the) overall progress status,
00397     // to account for the event that is being popped out of the event
00398     // queue.
00399     ++_progressStatus;
00400     
00401     // Remove the event, which has just been retrieved
00402     _eventList.erase (itEvent);
00403 
00404 
00412     // Retrieve the progress status specific to that event type
00413     stdair::ProgressStatus lEventTypeProgressStatus = getStatus (lEventType);
00414 
00415     // Increase the current number of events
00416     ++lEventTypeProgressStatus;
00417 
00418     // Store back the progress status
00419     setStatus (lEventType, lEventTypeProgressStatus);
00420 
00421     // Update the progress status of the progress status set, specific to
00422     // the event type.
00423     oProgressStatusSet.setTypeSpecificStatus (lEventTypeProgressStatus);
00424 
00428     // Update the overall progress status of the progress status set.
00429     oProgressStatusSet.setOverallStatus (_progressStatus);
00430 
00431     //
00432     return oProgressStatusSet;
00433   }
00434 
00435   // //////////////////////////////////////////////////////////////////////
00436   bool EventQueue::addEvent (stdair::EventStruct& ioEventStruct) {
00437     bool insertionSucceeded =
00438       _eventList.insert (stdair::EventListElement_T (ioEventStruct.getEventTimeStamp(),
00439                                                      ioEventStruct)).second;
00440 
00453     const unsigned int idx = 0;
00454     while (insertionSucceeded == false && idx != 1e3) {
00455       // Increment the date-time stamp (expressed in milliseconds)
00456       ioEventStruct.incrementEventTimeStamp();
00457 
00458       // Retry to insert into the event queue
00459       insertionSucceeded =
00460         _eventList.insert (stdair::EventListElement_T (ioEventStruct.getEventTimeStamp(),
00461                                                        ioEventStruct)).second;
00462     }
00463     assert (idx != 1e3);
00464 
00465     return insertionSucceeded;
00466   }
00467   
00468   // //////////////////////////////////////////////////////////////////////
00469   bool EventQueue::hasEventDateTime (const stdair::DateTime_T& iDateTime) {
00470 
00471     bool hasSearchEventBeenSucessful = true;
00472 
00478     const stdair::Duration_T lDuration =
00479       iDateTime - stdair::DEFAULT_EVENT_OLDEST_DATETIME;
00480     const stdair::LongDuration_T lDateTimeStamp =
00481       lDuration.total_milliseconds();
00482 
00483     // Searches the container for an element with iDateTime as key
00484     stdair::EventList_T::iterator itEvent =
00485       _eventList.find (lDateTimeStamp);
00486 
00487     // An iterator to map::end means the specified key has not found in the
00488     // container.
00489     if (itEvent == _eventList.end()) {
00490       hasSearchEventBeenSucessful = false;
00491     }
00492 
00493     return hasSearchEventBeenSucessful;
00494 
00495   }
00496 
00497 }