/******************************************************************* * * DESCRIPTION: Class NCMessageBag * * AUTHOR: Qi (Jacky) Liu * * EMAIL: mailto://liuqi@sce.carleton.ca * * DATE: Sept, 2005 * *******************************************************************/ #include "NCmsgbag.h" //header file #include "message.h" #include "except.h" /******************************************************************* * Function Name: Constructor ********************************************************************/ NCMessageBag::NCMessageBag() : MessageBag() {} /******************************************************************* * Function Name: Destructor ********************************************************************/ NCMessageBag::~NCMessageBag() { eraseAll(); } /******************************************************************* * Function Name: add() * Description: This function can add msgs with different time stamps * into the NCMessageBag, the msgtime keeps track of the * minimal time among the msgs in the bag. ********************************************************************/ MessageBag &NCMessageBag::add( const BasicPortMessage* msg) { if (count == 0) { //if the bag is empty, the new msgtime is the time of the newly added msg msgtime = msg->time(); } else { //if the bag is not empty, msgtime is the current MIN time among msgs already in the bag //now, compare it with the time of the msg that is going to be added, and get the new MIN if(msg->time() < msgtime){ //new MIN found msgtime = msg->time(); } } msgs[msg->port().name()].push_back( msg ); count++; return *this; } /******************************************************************* * Function Name: getMessageWithMinTime() * Description: This function retrieves all (X) msgs in the bag with time * stamp equal to the "msgtime" (the current MIN time) * It returns a list ********************************************************************/ MessageBag::MessageList NCMessageBag::getMessageWithMinTime() { MessageBag::MessageList minTimeMsgs; MessageBag::iterator cursor = begin(); //search all msgs in the bag for( ; cursor != end(); cursor++ ) { if((*cursor)->time() == time()){ //this msg has time "msgtime" //add it to the list "minTimeMsgs" minTimeMsgs.push_back( (*cursor) ); } } return minTimeMsgs; } /******************************************************************* * Function Name: removeMessageWithMinTime() * Description: this function removes all (X) msgs in the bag with time * stamp equal to the "msgtime" (the current MIN time); also * it advances the "msgtime" to the next MIN time among the * remaining msgs in the bag. ********************************************************************/ void NCMessageBag::removeMessageWithMinTime(){ MessagesOnPort::const_iterator cursor; MessageList::const_iterator portmsgs; list closeEntries; //the KEYs of the map that have empty VALUEs after removal for( cursor = msgs.begin(); cursor != msgs.end(); cursor++) { MessageList remainList; //list to temporarily hold msgs that will not be removed MessageList removeList; //list to temporarily hold msgs that will be removed MessageList currentList = cursor->second; //the current list of msgs we are working on for( portmsgs = currentList.begin(); portmsgs != currentList.end(); portmsgs++) { if((*portmsgs)->time() == time()){ //should be removed removeList.push_back(*portmsgs); } else { remainList.push_back(*portmsgs); } } //end inner for loop //one list done, replace it, change count, and delete the original one count = count - removeList.size(); //update the msg count //clean up the removeList for(portmsgs = removeList.begin(); portmsgs != removeList.end(); portmsgs++){ delete (*portmsgs); } //end for removeList.erase( removeList.begin(), removeList.end() ); if(remainList.size() != 0){ msgs[cursor->first] = remainList; //replace the list for the port } else { //we need to close this map entry! closeEntries.push_back(cursor->first); } //clean up the currentList currentList.erase( currentList.begin(), currentList.end() ); } //end outer for loop //close empty map entries for(list::const_iterator it = closeEntries.begin(); it != closeEntries.end(); it++){ msgs.erase(*it); } //now advance the msgtime to the next minimal time among the remaining msgs calculateNewMin(); } /******************************************************************* * Function Name: removeMessageWithTimeGreaterOrEqual * Description: this function removes all (X) msgs in the bag with time * stamp >= the given time; Also it adjusts the "msgtime" * to the MIN time among the remaining msgs in the bag. ********************************************************************/ void NCMessageBag::removeMessageWithTimeGreaterOrEqual( const VTime& rollbackTime ){ MessagesOnPort::const_iterator cursor; MessageList::const_iterator portmsgs; list closeEntries; //the KEYs of the map that have empty VALUEs after removal for( cursor = msgs.begin(); cursor != msgs.end(); cursor++) { MessageList remainList; //list to temporarily hold msgs that will not be removed MessageList removeList; //list to temporarily hold msgs that will be removed MessageList currentList = cursor->second; //the current list of msgs we are working on for( portmsgs = currentList.begin(); portmsgs != currentList.end(); portmsgs++) { if( (rollbackTime < (*portmsgs)->time()) || (rollbackTime == (*portmsgs)->time()) ){ removeList.push_back(*portmsgs); } else { remainList.push_back(*portmsgs); } } //end inner for loop //one list done, replace it, change count, and delete the original one count = count - removeList.size(); //update the msg count //clean up the removeList for(portmsgs = removeList.begin(); portmsgs != removeList.end(); portmsgs++){ delete (*portmsgs); } //end for removeList.erase( removeList.begin(), removeList.end() ); if(remainList.size() != 0){ msgs[cursor->first] = remainList; //replace the list for the port } else { //we need to close this map entry! closeEntries.push_back(cursor->first); } //clean up the currentList currentList.erase( currentList.begin(), currentList.end() ); } //end outer for loop //close empty map entries for(list::const_iterator it = closeEntries.begin(); it != closeEntries.end(); it++){ msgs.erase(*it); } //now advance the msgtime to the next minimal time among the remaining msgs calculateNewMin(); } /******************************************************************* * Function Name: calculateNewMin() * Description: this function advances the msgtime to the next MIN time * among the msgs in the bag. It is used by removeMessageWithMinTime() * If there are no msgs in the bag when this function is called, * the msgtime is set to VTime::Inf ********************************************************************/ void NCMessageBag::calculateNewMin(){ msgtime = VTime::Inf; MessageBag::iterator cursor = begin(); //search all msgs in the bag for( ; cursor != end(); cursor++ ) { if((*cursor)->time() < msgtime) { msgtime = (*cursor)->time(); } } } //Note: this function makes use of the asString() function of the BasicPortMessage class // to show the content of the NCMessageBag ostream& operator<<(ostream& os, const NCMessageBag& bag){ os << "\tNCMessageBag " << flush; if( bag.size() != 0 ) { os << endl << flush; MessageBag::iterator cursor = bag.begin(); //print out all msgs in the bag for( ; cursor != bag.end(); cursor++ ) { os << (*cursor)->asString() << " [Address = " << (*cursor) << "]" << endl << flush; } } else { os << " -> EMPTY" << endl << flush; } os << "\t------------- NCMessageBag End ----------------" << endl; return os; }