StdAir Logo  0.43.0
C++ Standard Airline IT Library
EventQueue.cpp
Go to the documentation of this file.
00001 // //////////////////////////////////////////////////////////////////////
00002 // Import section
00003 // //////////////////////////////////////////////////////////////////////
00004 // STL
00005 #include <cassert>
00006 // Boost
00007 #include <boost/make_shared.hpp>
00008 // StdAir
00009 #include <stdair/stdair_exceptions.hpp>
00010 #include <stdair/basic/BasConst_Event.hpp>
00011 #include <stdair/bom/EventStruct.hpp>
00012 #include <stdair/bom/EventQueue.hpp>
00013 #include <stdair/service/Logger.hpp>
00014 
00015 namespace stdair {
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   Count_T EventQueue::getQueueSize() const {
00065     return _eventList.size();
00066   }
00067   
00068   // //////////////////////////////////////////////////////////////////////
00069   bool EventQueue::isQueueEmpty() const {
00070     return _eventList.empty();
00071   }
00072   
00073   // //////////////////////////////////////////////////////////////////////
00074   bool EventQueue::isQueueDone() const {
00075     const bool isQueueEmpty = _eventList.empty();
00076     return isQueueEmpty;
00077   }
00078 
00079   // //////////////////////////////////////////////////////////////////////
00080   void EventQueue::reset() {
00081     // Reset only the current number of events, not the expected one
00082     _progressStatus.reset();
00083     
00084     // Empty the list of events
00085     _eventList.clear();
00086 
00087     // Reset the progress statuses for all the event types
00088     for (ProgressStatusMap_T::iterator itProgressStatus =
00089            _progressStatusMap.begin();
00090          itProgressStatus != _progressStatusMap.end(); ++itProgressStatus) {
00091       ProgressStatus& lProgressStatus = itProgressStatus->second;
00092       lProgressStatus.reset();
00093     }
00094 
00095   }
00096   
00097   // //////////////////////////////////////////////////////////////////////
00098   const Count_T& EventQueue::
00099   getCurrentNbOfEvents (const EventType::EN_EventType& iType) const {
00100 
00101     // Retrieve the ProgressStatus structure corresponding to the
00102     // given event type
00103     ProgressStatusMap_T::const_iterator itProgressStatus =
00104       _progressStatusMap.find (iType);
00105     if (itProgressStatus == _progressStatusMap.end()) {
00106       //
00107       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00108                         << "EventQueue: " << display());
00109       assert (false);
00110     }
00111     
00112     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00113     return lProgressStatus.getCurrentNb();
00114   }
00115 
00116   // //////////////////////////////////////////////////////////////////////
00117   const Count_T& EventQueue::
00118   getExpectedTotalNbOfEvents (const EventType::EN_EventType& iType) const {
00119 
00120     // Retrieve the ProgressStatus structure corresponding to the
00121     // given event type
00122     ProgressStatusMap_T::const_iterator itProgressStatus =
00123       _progressStatusMap.find (iType);
00124     if (itProgressStatus == _progressStatusMap.end()) {
00125       std::ostringstream oStr;
00126       oStr << "No ProgressStatus structure can be retrieved in the EventQueue '"
00127            << display() << "'. The EventQueue should be initialised, e.g., by "
00128            << "calling a buildSampleBom() method.";
00129       //
00130       STDAIR_LOG_ERROR (oStr.str());
00131       throw EventQueueException (oStr.str());
00132     }
00133     
00134     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00135     return lProgressStatus.getExpectedNb();
00136   }
00137 
00138   // //////////////////////////////////////////////////////////////////////
00139   const Count_T& EventQueue::
00140   getActualTotalNbOfEvents (const EventType::EN_EventType& iType) const {
00141 
00142     // Retrieve the ProgressStatus structure corresponding to the
00143     // given event type
00144     ProgressStatusMap_T::const_iterator itProgressStatus =
00145       _progressStatusMap.find (iType);
00146     if (itProgressStatus == _progressStatusMap.end()) {
00147       //
00148       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00149                         << "EventQueue: " << display());
00150       assert (false);
00151     }
00152     
00153     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00154     return lProgressStatus.getActualNb();
00155   }
00156 
00157   // //////////////////////////////////////////////////////////////////////
00158   void EventQueue::updateStatus (const EventType::EN_EventType& iType,
00159                                  const ProgressStatus& iProgressStatus) {
00160 
00161     // Retrieve, if existing, the ProgressStatus structure
00162     // corresponding to the given event type
00163     ProgressStatusMap_T::iterator itProgressStatus =
00164       _progressStatusMap.find (iType);
00165     if (itProgressStatus == _progressStatusMap.end()) {
00166       const bool hasInsertBeenSuccessful =
00167         _progressStatusMap.insert (ProgressStatusMap_T::
00168                                    value_type (iType, iProgressStatus)).second;
00169       
00170       if (hasInsertBeenSuccessful == false) {
00171         STDAIR_LOG_ERROR ("No progress_status can be inserted "
00172                           << "for the following event type: "
00173                           << EventType::getLabel(iType)
00174                           << ". EventQueue: " << toString());
00175         throw EventException ("No progress_status can be inserted for the "
00176                               "following event type: "
00177                               + EventType::getLabel(iType)
00178                               + ". EventQueue: " + toString());
00179       }
00180 
00181       return;
00182     }
00183     
00184     ProgressStatus& lProgressStatus = itProgressStatus->second;
00185 
00186     // Update the progress status
00187     const Count_T& lCurrentNb = iProgressStatus.getCurrentNb();
00188     lProgressStatus.setCurrentNb (lCurrentNb);
00189 
00190     const Count_T& lExpectedNb = iProgressStatus.getExpectedNb();
00191     lProgressStatus.setExpectedNb(lProgressStatus.getExpectedNb() + lExpectedNb);
00192 
00193     const Count_T& lActualNb = iProgressStatus.getActualNb();
00194     lProgressStatus.setActualNb (lProgressStatus.getActualNb() + lActualNb);
00195   }
00196 
00197   // //////////////////////////////////////////////////////////////////////
00198   void EventQueue::
00199   addStatus (const EventType::EN_EventType& iType,
00200              const NbOfEvents_T& iExpectedTotalNbOfEvents) {
00201     
00202     // Initialise the progress status object
00203     const Count_T lExpectedTotalNbOfEventsInt =
00204       std::floor (iExpectedTotalNbOfEvents);
00205     const ProgressStatus lProgressStatus (lExpectedTotalNbOfEventsInt);
00206       
00207     // Update the progress status for the given event type
00208     updateStatus (iType, lProgressStatus);
00209     
00210     // Update the overall progress status
00211     _progressStatus.setExpectedNb (_progressStatus.getExpectedNb()
00212                                    + iExpectedTotalNbOfEvents);
00213 
00214     _progressStatus.setActualNb (_progressStatus.getActualNb()
00215                                  + iExpectedTotalNbOfEvents);
00216   }
00217 
00218   // //////////////////////////////////////////////////////////////////////
00219   void EventQueue::updateStatus (const EventType::EN_EventType& iType,
00220                                  const NbOfEvents_T& iActualNbOfEvents) {
00221 
00222     // Initialise the progress status object for the type key
00223     Count_T lActualNbOfEventsInt = std::floor (iActualNbOfEvents);
00224       
00225     // Update the progress status for the corresponding content type key
00226     ProgressStatusMap_T::iterator itProgressStatus =
00227       _progressStatusMap.find (iType);
00228     if (itProgressStatus != _progressStatusMap.end()) {
00229       ProgressStatus& lProgressStatus = itProgressStatus->second;
00230       //
00231       lActualNbOfEventsInt += lProgressStatus.getActualNb();
00232       //
00233       lProgressStatus.setActualNb (lActualNbOfEventsInt);
00234     }
00235   }
00236 
00237   // //////////////////////////////////////////////////////////////////////
00238   void EventQueue::setStatus (const EventType::EN_EventType& iType,
00239                               const ProgressStatus& iProgressStatus) {
00240 
00241     // Retrieve the ProgressStatus structure corresponding to the
00242     // given event type
00243     ProgressStatusMap_T::iterator itProgressStatus =
00244       _progressStatusMap.find (iType);
00245     // assert (itProgressStatus != _progressStatusMap.end());
00246     if (itProgressStatus != _progressStatusMap.end()) {
00247       // Update the ProgressStatus structure
00248       itProgressStatus->second = iProgressStatus;
00249     }
00250   }
00251 
00252   // //////////////////////////////////////////////////////////////////////
00253   ProgressStatus EventQueue::
00254   getStatus (const EventType::EN_EventType& iType) const {
00255 
00256     // Retrieve the ProgressStatus structure corresponding to the
00257     // given event type
00258     ProgressStatusMap_T::const_iterator itProgressStatus =
00259       _progressStatusMap.find (iType);
00260     if (itProgressStatus != _progressStatusMap.end()) {
00261       const ProgressStatus& oProgressStatus = itProgressStatus->second;
00262       return oProgressStatus;
00263     }
00264 
00265     return ProgressStatus();
00266   }
00267 
00268   // //////////////////////////////////////////////////////////////////////
00269   ProgressPercentage_T EventQueue::
00270   calculateProgress (const EventType::EN_EventType& iType) const {
00271 
00272     // Retrieve the ProgressStatus structure corresponding to the
00273     // given event type
00274     ProgressStatusMap_T::const_iterator itProgressStatus =
00275       _progressStatusMap.find (iType);
00276     if (itProgressStatus == _progressStatusMap.end()) {
00277       //
00278       STDAIR_LOG_ERROR ("No ProgressStatus structure can be retrieved in the "
00279                         << "EventQueue: " << display());
00280       assert (false);
00281     }
00282     
00283     const ProgressStatus& lProgressStatus = itProgressStatus->second;
00284     return lProgressStatus.progress();
00285   }
00286 
00287   // //////////////////////////////////////////////////////////////////////
00288   ProgressStatusSet EventQueue::popEvent (EventStruct& ioEventStruct) {
00289     assert (_eventList.empty() == false);
00290 
00294     // Get an iterator on the first event (sorted by date-time stamps)
00295     EventList_T::iterator itEvent = _eventList.begin();
00296 
00303     ioEventStruct = itEvent->second;
00304     // Retrieve the event type
00305     const EventType::EN_EventType& lEventType = ioEventStruct.getEventType();
00306     ProgressStatusSet oProgressStatusSet (lEventType);
00307   
00308     // Update the (current number part of the) overall progress status,
00309     // to account for the event that is being popped out of the event
00310     // queue.
00311     ++_progressStatus;
00312     
00313     // Remove the event, which has just been retrieved
00314     _eventList.erase (itEvent);
00315 
00316 
00324     // Retrieve the progress status specific to that event type
00325     ProgressStatus lEventTypeProgressStatus = getStatus (lEventType);
00326 
00327     // Increase the current number of events
00328     ++lEventTypeProgressStatus;
00329 
00330     // Store back the progress status
00331     setStatus (lEventType, lEventTypeProgressStatus);
00332 
00333     // Update the progress status of the progress status set, specific to
00334     // the event type.
00335     oProgressStatusSet.setTypeSpecificStatus (lEventTypeProgressStatus);
00336 
00340     // Update the overall progress status of the progress status set.
00341     oProgressStatusSet.setOverallStatus (_progressStatus);
00342 
00343     //
00344     return oProgressStatusSet;
00345   }
00346 
00347   // //////////////////////////////////////////////////////////////////////
00348   bool EventQueue::addEvent (EventStruct& ioEventStruct) {
00349     bool insertionSucceeded =
00350       _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
00351                                              ioEventStruct)).second;
00352 
00365     const unsigned int idx = 0;
00366     while (insertionSucceeded == false && idx != 1e3) {
00367       // Retrieve the date-time stamp (expressed in milliseconds)
00368       LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
00369       ++lEventTimeStamp;
00370 
00371       // Retry to insert into the event queue
00372       insertionSucceeded =
00373         _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
00374                                                ioEventStruct)).second;
00375     }
00376     assert (idx != 1e3);
00377 
00378     return insertionSucceeded;
00379   }
00380 
00381 }