MessageObserver.cc

Go to the documentation of this file.
00001 //
00002 // This program is free software; you can redistribute it and/or
00003 // modify it under the terms of the GNU General Public License
00004 // as published by the Free Software Foundation; either version 2
00005 // of the License, or (at your option) any later version.
00006 //
00007 // This program is distributed in the hope that it will be useful,
00008 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00009 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010 // GNU General Public License for more details.
00011 //
00012 // You should have received a copy of the GNU General Public License
00013 // along with this program; if not, write to the Free Software
00014 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00015 //
00016 
00022 #include <assert.h>
00023 #include <sstream>
00024 #include <omnetpp.h>
00025 #include "MessageObserver.h"
00026 #include "ALMTestTracedMessage_m.h"
00027 
00028 Define_Module(MessageObserver);
00029 
00030 MessageObserver::MessageObserver() {
00031     gcTimer = new cMessage("garbage_collection");
00032     gcInterval = 1.0;
00033     cacheMaxAge = 10.0;
00034 }
00035 
00036 MessageObserver::~MessageObserver() {
00037     cancelAndDelete(gcTimer);
00038 }
00039 
00040 void MessageObserver::initialize() {
00041     WATCH_MAP(groups);
00042     WATCH_MAP(joinedAt);
00043     WATCH_MAP(receivedAt);
00044     
00045     gcInterval = par("gcInterval");
00046     cacheMaxAge = par("cacheMaxAge");
00047 
00048     if (gcInterval > 0.0)
00049         scheduleAt(OPP::simTime() + gcInterval, gcTimer);
00050 }
00051 
00052 void MessageObserver::finish() {
00053     uint64_t totalSent = 0;
00054     uint64_t totalReceived = 0;
00055     for (std::map<OverlayKey, MulticastGroup>::iterator i = groups.begin(); i != groups.end(); ++i) {
00056         std::stringstream message;
00057         message << "MessageObserver: Group " << i->first;
00058         std::string name;
00059 
00060         name = message.str() + " Sent Messages";
00061         recordScalar(name.c_str(), (double)i->second.sent);
00062 
00063         name = message.str() + " Received Messages";
00064         recordScalar(name.c_str(), (double)i->second.received);
00065 
00066         name = message.str() + " Delivered Percentage";
00067         recordScalar(name.c_str(), ((double)i->second.received * 100.0) / (double)i->second.sent);
00068 
00069         totalSent += i->second.sent;
00070         totalReceived += i->second.received;
00071     }
00072 
00073     recordScalar("MessageObserver: Total Sent Messages", (double)totalSent);
00074     recordScalar("MessageObserver: Total Received Messages", (double)totalReceived);
00075     recordScalar("MessageObserver: Total Delivered Percentage", ((double)totalReceived * 100.0) / (double)totalSent);
00076 }
00077 
00078 void MessageObserver::handleMessage(cMessage* msg) {
00079     if (msg == gcTimer) {
00080         simtime_t now = OPP::simTime();
00081         std::map<NodeMessagePair, simtime_t>::iterator i, iPrev;
00082         i = receivedAt.begin();
00083         while (i != receivedAt.end()) {
00084             if (now - i->second >= cacheMaxAge) {
00085                 iPrev = i;
00086                 ++i;
00087                 receivedAt.erase(iPrev);
00088             }
00089             else {
00090                 ++i;
00091             }
00092         }
00093         scheduleAt(OPP::simTime() + gcInterval, gcTimer);
00094     }
00095 }
00096 
00100 void MessageObserver::joinedGroup(int moduleId, OverlayKey groupId) {
00101     groups[groupId].size += 1;
00102     joinedAt[NodeGroupPair(moduleId, groupId)] = OPP::simTime();
00103 }
00104 
00108 void MessageObserver::leftGroup(int moduleId, OverlayKey groupId) {
00109     std::map<OverlayKey, MulticastGroup>::iterator iter = groups.find(groupId);
00110     if (iter == groups.end()) {
00111         EV << "Warning: MessageObserver asked to remove node from nonexistent group " << groupId.toString();
00112     }
00113     else if (iter->second.size == 0) {
00114         EV << "Warning: MessageObserver asked to remove node from empty group " << groupId.toString();
00115     }
00116     else {
00117         iter->second.size -= 1;
00118     }
00119     joinedAt.erase(NodeGroupPair(moduleId, groupId));
00120 }
00121 
00126 void MessageObserver::sentMessage(ALMTestTracedMessage* msg) {
00127     if (msg == NULL) {
00128         error("%s called with null message.", __PRETTY_FUNCTION__);
00129     }
00130 
00131     std::map<OverlayKey, MulticastGroup>::iterator iter;
00132     iter = groups.find(msg->getGroupId());
00133     if (iter == groups.end()) {
00134         EV << "Warning: MessageObserver notified of sent message for nonexistent group " << msg->getGroupId().toString();
00135     }
00136     else if (iter->second.size == 0) {
00137         EV << "Warning: MessageObserver notified of sent message for empty group " << msg->getGroupId().toString();
00138     }
00139     else {
00140         iter->second.sent += iter->second.size - 1;
00141     }
00142 }
00143 
00147 void MessageObserver::receivedMessage(ALMTestTracedMessage* msg) {
00148     if (msg == NULL) {
00149         error("%s called with null message.", __PRETTY_FUNCTION__);
00150     }
00151 
00152     std::map<OverlayKey, MulticastGroup>::iterator iGroup;
00153     iGroup = groups.find(msg->getGroupId());
00154     if (iGroup == groups.end()) {
00155         EV << "Warning: MessageObserver notified of received message for nonexistent group " << msg->getGroupId().toString();
00156     }
00157     else if (iGroup->second.size == 0) {
00158         EV << "Warning: MessageObserver notified of received message for empty group " << msg->getGroupId().toString();
00159     }
00160     else if (msg->getSenderId() != msg->getReceiverId()) {
00161 
00162         // Only count if message was received after joining
00163         std::map<NodeGroupPair, simtime_t>::iterator iJoinInfo;
00164         iJoinInfo = joinedAt.find(NodeGroupPair(msg->getReceiverId(), msg->getGroupId()));
00165 
00166         if (iJoinInfo != joinedAt.end() && iJoinInfo->second < msg->getTimestamp()) {
00167             
00168             // Check if this message has not already been received
00169             NodeMessagePair nmp = NodeMessagePair(msg->getReceiverId(), msg->getMcastId());
00170             if (receivedAt.find(nmp) == receivedAt.end()) {
00171                 iGroup->second.received += 1;
00172                 receivedAt[nmp] = msg->getTimestamp();
00173             }
00174         }
00175     }
00176     else {
00177         // TODO: Count looped messages here?
00178     }
00179 }
00180 
00181 std::ostream& operator<< (std::ostream& os, MessageObserver::MulticastGroup const & mg) {
00182     return os << "Nodes: " << mg.size << "; Messages Sent: " << mg.sent
00183         << ", Received: " << mg.received << ", Dropped: " << (mg.sent - mg.received);
00184 }
00185 
00186 std::ostream& operator<< (std::ostream& os, MessageObserver::NodeGroupPair const & ngp) {
00187     cModule* module = OPP::cSimulation::getActiveSimulation()->getModule(ngp.first);
00188     return os << "(" << (module != NULL ? module->getFullPath() : "Deleted node")
00189         << ", " << ngp.second << ")";
00190 }
00191 
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3