StdAir Logo  0.45.0
C++ Standard Airline IT Object Library
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/bom/EventQueue.hpp>
00011 #include <stdair/service/Logger.hpp>
00012 
00013 namespace stdair {
00014   
00015   // //////////////////////////////////////////////////////////////////////
00016   EventQueue::EventQueue()
00017     : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
00018       _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
00019                        stdair::DEFAULT_PROGRESS_STATUS) {
00020   }
00021   
00022   // //////////////////////////////////////////////////////////////////////
00023   EventQueue::EventQueue (const Key_T& iKey)
00024     : _key (iKey), _parent (NULL),
00025       _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
00026                        stdair::DEFAULT_PROGRESS_STATUS) {
00027   }
00028   
00029   // //////////////////////////////////////////////////////////////////////
00030   EventQueue::EventQueue (const EventQueue& iEventQueue)
00031     : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
00032       _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
00033                        stdair::DEFAULT_PROGRESS_STATUS) {
00034     assert (false);
00035   }
00036   
00037   // //////////////////////////////////////////////////////////////////////
00038   EventQueue::~EventQueue() {
00039     _eventList.clear();
00040   }
00041   
00042   // //////////////////////////////////////////////////////////////////////
00043   std::string EventQueue::toString() const {
00044     std::ostringstream oStr;
00045     oStr << "(" << _eventList.size() << ") "
00046          << _progressStatus.getCurrentNb() << "/{"
00047          << _progressStatus.getExpectedNb() << ","
00048          << _progressStatus.getActualNb() << "}";
00049     return oStr.str();
00050   }
00051 
00052   // //////////////////////////////////////////////////////////////////////
00053   std::string EventQueue::display() const {
00054     std::ostringstream oStr;
00055 
00056     oStr << toString();
00057     
00058     return oStr.str();
00059   }
00060 
00061   // //////////////////////////////////////////////////////////////////////
00062   Count_T EventQueue::getQueueSize() const {
00063     return _eventList.size();
00064   }
00065   
00066   // //////////////////////////////////////////////////////////////////////
00067   bool EventQueue::isQueueEmpty() const {
00068     return _eventList.empty();
00069   }
00070   
00071   // //////////////////////////////////////////////////////////////////////
00072   bool EventQueue::isQueueDone() const {
00073     const bool isQueueEmpty = _eventList.empty();
00074     return isQueueEmpty;
00075   }
00076 
00077   // //////////////////////////////////////////////////////////////////////
00078   void EventQueue::reset() {
00079     // Reset only the current number of events, not the expected one
00080     _progressStatus.reset();
00081     
00082     // Empty the list of events
00083     _eventList.clear();
00084 
00085     // Reset the progress statuses for all the event types
00086     for (ProgressStatusMap_T::iterator itProgressStatus =
00087            _progressStatusMap.begin();
00088          itProgressStatus != _progressStatusMap.end(); ++itProgressStatus) {
00089       ProgressStatus& lProgressStatus = itProgressStatus->second;
00090       lProgressStatus.reset();
00091     }
00092 
00093   }
00094   
00095   // //////////////////////////////////////////////////////////////////////
00096   const Count_T& EventQueue::
00097   getCurrentNbOfEvents (const EventType::EN_EventType& iType) const {
00098 
00099     // Retrieve the ProgressStatus structure corresponding to the
00100     // given event type
00101     ProgressStatusMap_T::const_iterator itProgressStatus =
00102       _progressStatusMap.find (iType);
00103     if (itProgressStatus == _progressStatusMap.end()) {
00104       //
00105       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00106                         << "EventQueue: " << display());
00107       assert (false);
00108     }
00109     
00110     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00111     return lProgressStatus.getCurrentNb();
00112   }
00113 
00114   // //////////////////////////////////////////////////////////////////////
00115   const Count_T& EventQueue::
00116   getExpectedTotalNbOfEvents (const EventType::EN_EventType& iType) const {
00117 
00118     // Retrieve the ProgressStatus structure corresponding to the
00119     // given event type
00120     ProgressStatusMap_T::const_iterator itProgressStatus =
00121       _progressStatusMap.find (iType);
00122     if (itProgressStatus == _progressStatusMap.end()) {
00123       std::ostringstream oStr;
00124       oStr << "No ProgressStatus structure can be retrieved in the EventQueue '"
00125            << display() << "'. The EventQueue should be initialised, e.g., by "
00126            << "calling a buildSampleBom() method.";
00127       //
00128       STDAIR_LOG_ERROR (oStr.str());
00129       throw EventQueueException (oStr.str());
00130     }
00131     
00132     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00133     return lProgressStatus.getExpectedNb();
00134   }
00135 
00136   // //////////////////////////////////////////////////////////////////////
00137   const Count_T& EventQueue::
00138   getActualTotalNbOfEvents (const EventType::EN_EventType& iType) const {
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_ERROR ("No ProgressStatus structure can be retrieved in the "
00147                         << "EventQueue: " << display());
00148       assert (false);
00149     }
00150     
00151     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00152     return lProgressStatus.getActualNb();
00153   }
00154 
00155   // //////////////////////////////////////////////////////////////////////
00156   void EventQueue::updateStatus (const EventType::EN_EventType& iType,
00157                                  const ProgressStatus& iProgressStatus) {
00158 
00159     // Retrieve, if existing, the ProgressStatus structure
00160     // corresponding to the given event type
00161     ProgressStatusMap_T::iterator itProgressStatus =
00162       _progressStatusMap.find (iType);
00163     if (itProgressStatus == _progressStatusMap.end()) {
00164       const bool hasInsertBeenSuccessful =
00165         _progressStatusMap.insert (ProgressStatusMap_T::
00166                                    value_type (iType, iProgressStatus)).second;
00167       
00168       if (hasInsertBeenSuccessful == false) {
00169         STDAIR_LOG_ERROR ("No progress_status can be inserted "
00170                           << "for the following event type: "
00171                           << EventType::getLabel(iType)
00172                           << ". EventQueue: " << toString());
00173         throw EventException ("No progress_status can be inserted for the "
00174                               "following event type: "
00175                               + EventType::getLabel(iType)
00176                               + ". EventQueue: " + toString());
00177       }
00178 
00179       return;
00180     }
00181     
00182     ProgressStatus& lProgressStatus = itProgressStatus->second;
00183 
00184     // Update the progress status
00185     const Count_T& lCurrentNb = iProgressStatus.getCurrentNb();
00186     lProgressStatus.setCurrentNb (lCurrentNb);
00187 
00188     const Count_T& lExpectedNb = iProgressStatus.getExpectedNb();
00189     lProgressStatus.setExpectedNb(lProgressStatus.getExpectedNb() + lExpectedNb);
00190 
00191     const Count_T& lActualNb = iProgressStatus.getActualNb();
00192     lProgressStatus.setActualNb (lProgressStatus.getActualNb() + lActualNb);
00193   }
00194 
00195   // //////////////////////////////////////////////////////////////////////
00196   void EventQueue::
00197   addStatus (const EventType::EN_EventType& iType,
00198              const NbOfEvents_T& iExpectedTotalNbOfEvents) {
00199     
00200     // Initialise the progress status object
00201     const Count_T lExpectedTotalNbOfEventsInt =
00202       static_cast<const Count_T> (std::floor (iExpectedTotalNbOfEvents));
00203     const ProgressStatus lProgressStatus (lExpectedTotalNbOfEventsInt);
00204       
00205     // Update the progress status for the given event type
00206     updateStatus (iType, lProgressStatus);
00207     
00208     // Update the overall progress status
00209     const Count_T lExpectedNb = 
00210       static_cast<const Count_T> (_progressStatus.getExpectedNb()
00211                                   + iExpectedTotalNbOfEvents);
00212     _progressStatus.setExpectedNb (lExpectedNb);
00213 
00214     const Count_T lActualNb = 
00215       static_cast<const Count_T> (_progressStatus.getActualNb()
00216                                   + iExpectedTotalNbOfEvents);
00217     _progressStatus.setActualNb (lActualNb);
00218   }
00219 
00220   // //////////////////////////////////////////////////////////////////////
00221   void EventQueue::updateStatus (const EventType::EN_EventType& iType,
00222                                  const NbOfEvents_T& iActualNbOfEvents) {
00223 
00224     // Initialise the progress status object for the type key
00225     Count_T lActualNbOfEventsInt =
00226       static_cast<const Count_T> (std::floor (iActualNbOfEvents));
00227       
00228     // Update the progress status for the corresponding content type key
00229     ProgressStatusMap_T::iterator itProgressStatus =
00230       _progressStatusMap.find (iType);
00231     if (itProgressStatus != _progressStatusMap.end()) {
00232       ProgressStatus& lProgressStatus = itProgressStatus->second;
00233       //
00234       lActualNbOfEventsInt += lProgressStatus.getActualNb();
00235       //
00236       lProgressStatus.setActualNb (lActualNbOfEventsInt);
00237     }
00238   }
00239 
00240   // //////////////////////////////////////////////////////////////////////
00241   void EventQueue::setStatus (const EventType::EN_EventType& iType,
00242                               const ProgressStatus& iProgressStatus) {
00243 
00244     // Retrieve the ProgressStatus structure corresponding to the
00245     // given event type
00246     ProgressStatusMap_T::iterator itProgressStatus =
00247       _progressStatusMap.find (iType);
00248     // assert (itProgressStatus != _progressStatusMap.end());
00249     if (itProgressStatus != _progressStatusMap.end()) {
00250       // Update the ProgressStatus structure
00251       itProgressStatus->second = iProgressStatus;
00252     }
00253   }
00254 
00255   // //////////////////////////////////////////////////////////////////////
00256   ProgressStatus EventQueue::
00257   getStatus (const EventType::EN_EventType& iType) const {
00258 
00259     // Retrieve the ProgressStatus structure corresponding to the
00260     // given event type
00261     ProgressStatusMap_T::const_iterator itProgressStatus =
00262       _progressStatusMap.find (iType);
00263     if (itProgressStatus != _progressStatusMap.end()) {
00264       const ProgressStatus& oProgressStatus = itProgressStatus->second;
00265       return oProgressStatus;
00266     }
00267 
00268     return ProgressStatus();
00269   }
00270 
00271   // //////////////////////////////////////////////////////////////////////
00272   ProgressPercentage_T EventQueue::
00273   calculateProgress (const EventType::EN_EventType& iType) const {
00274 
00275     // Retrieve the ProgressStatus structure corresponding to the
00276     // given event type
00277     ProgressStatusMap_T::const_iterator itProgressStatus =
00278       _progressStatusMap.find (iType);
00279     if (itProgressStatus == _progressStatusMap.end()) {
00280       //
00281       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00282                         << "EventQueue: " << display());
00283       assert (false);
00284     }
00285     
00286     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00287     return lProgressStatus.progress();
00288   }
00289 
00290   // //////////////////////////////////////////////////////////////////////
00291   ProgressStatusSet EventQueue::popEvent (EventStruct& ioEventStruct) {
00292     assert (_eventList.empty() == false);
00293 
00297     // Get an iterator on the first event (sorted by date-time stamps)
00298     EventList_T::iterator itEvent = _eventList.begin();
00299 
00306     ioEventStruct = itEvent->second;
00307     // Retrieve the event type
00308     const EventType::EN_EventType& lEventType = ioEventStruct.getEventType();
00309     ProgressStatusSet oProgressStatusSet (lEventType);
00310   
00311     // Update the (current number part of the) overall progress status,
00312     // to account for the event that is being popped out of the event
00313     // queue.
00314     ++_progressStatus;
00315     
00316     // Remove the event, which has just been retrieved
00317     _eventList.erase (itEvent);
00318 
00319 
00327     // Retrieve the progress status specific to that event type
00328     ProgressStatus lEventTypeProgressStatus = getStatus (lEventType);
00329 
00330     // Increase the current number of events
00331     ++lEventTypeProgressStatus;
00332 
00333     // Store back the progress status
00334     setStatus (lEventType, lEventTypeProgressStatus);
00335 
00336     // Update the progress status of the progress status set, specific to
00337     // the event type.
00338     oProgressStatusSet.setTypeSpecificStatus (lEventTypeProgressStatus);
00339 
00343     // Update the overall progress status of the progress status set.
00344     oProgressStatusSet.setOverallStatus (_progressStatus);
00345 
00346     //
00347     return oProgressStatusSet;
00348   }
00349 
00350   // //////////////////////////////////////////////////////////////////////
00351   bool EventQueue::addEvent (EventStruct& ioEventStruct) {
00352     bool insertionSucceeded =
00353       _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
00354                                              ioEventStruct)).second;
00355 
00368     const unsigned int idx = 0;
00369     while (insertionSucceeded == false && idx != 1e3) {
00370       // Retrieve the date-time stamp (expressed in milliseconds)
00371       LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
00372       ++lEventTimeStamp;
00373 
00374       // Retry to insert into the event queue
00375       insertionSucceeded =
00376         _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
00377                                                ioEventStruct)).second;
00378     }
00379     assert (idx != 1e3);
00380 
00381     return insertionSucceeded;
00382   }
00383 
00384 }