GlobalTraceManager Class Reference

#include <GlobalTraceManager.h>

List of all members.


Detailed Description

Parse a trace file and schedule node joins/leaves according to trace data.

If trace includes user action, send actions to application

Public Member Functions

void handleMessage (cMessage *msg)
void initialize (int stage)

Protected Member Functions

void readNextBlock ()
void scheduleNextEvent (double time, int nodeId, char *buf, int line)
void createNode (int nodeId)
void deleteNode (int nodeId)
cGate * getAppGateById (int nodeId)

Protected Attributes

UnderlayConfiguratorunderlayConfigurator
BootstrapOraclebootstrapOracle
 pointer to BootstrapOracle

Private Attributes

int fd
int filesize
int chunksize
int remain
int marginsize
int offset
char * buf
char * start
cMessage * nextRead

Static Private Attributes

static const int readPages = 32


Member Function Documentation

void GlobalTraceManager::handleMessage ( cMessage *  msg  ) 

00151 {
00152     if (!msg->isSelfMessage()) {
00153         delete msg;
00154         return;
00155     } else if ( msg == nextRead ) {
00156         readNextBlock();
00157         return;
00158     }
00159 
00160     GlobalTraceManagerMessage* traceMsg = check_and_cast<GlobalTraceManagerMessage*>(msg);
00161 
00162     if (strstr(traceMsg->name(), "JOIN") == traceMsg->name()) {
00163         createNode(traceMsg->getInternalNodeId());
00164     } else if (strstr(traceMsg->name(), "LEAVE") == traceMsg->name()) {
00165         deleteNode(traceMsg->getInternalNodeId());
00166     } else if (strstr(traceMsg->name(), "CONNECT_NODETYPES") == traceMsg->name()) {
00167         std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector();
00168         
00169         if (strVec.size() != 3) {
00170             throw new cException("GlobalTraceManager::"
00171                                  "handleMessage(): Invalid command");
00172         }
00173         
00174         int firstNodeType = atoi(strVec[1].c_str());
00175         int secondNodeType = atoi(strVec[2].c_str());
00176 
00177         bootstrapOracle->connectNodeTypes(firstNodeType, secondNodeType);
00178     } else if (strstr(traceMsg->name(), "DISCONNECT_NODETYPES") == traceMsg->name()) {
00179         std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector();
00180         
00181         if (strVec.size() != 3) {
00182             throw new cException("GlobalTraceManager::"
00183                                  "handleMessage(): Invalid command");
00184         }
00185         
00186         int firstNodeType = atoi(strVec[1].c_str());
00187         int secondNodeType = atoi(strVec[2].c_str());
00188         
00189         bootstrapOracle->disconnectNodeTypes(firstNodeType, secondNodeType);
00190     } else if (strstr(traceMsg->name(), "MERGE_BOOTSTRAPNODES") == traceMsg->name()) {
00191         std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector();
00192         
00193         if (strVec.size() != 4) {
00194             throw new cException("GlobalTraceManager::"
00195                                  "handleMessage(): Invalid command");
00196         }
00197         
00198         int toPartition = atoi(strVec[1].c_str());
00199         int fromPartition = atoi(strVec[2].c_str());
00200         int numNodes = atoi(strVec[3].c_str());
00201 
00202         bootstrapOracle->mergeBootstrapNodes(toPartition, fromPartition, numNodes);
00203     } else {
00204         sendDirect(msg, 0, getAppGateById(traceMsg->getInternalNodeId()));
00205         return; // don't delete Message
00206     }
00207 
00208     delete msg;
00209 }

void GlobalTraceManager::initialize ( int  stage  ) 

00029 {
00030     Enter_Method_Silent();
00031     
00032     // Nothing to do for us if there is no traceFile
00033     if (strlen(par("traceFile")) == 0)
00034         return;
00035 
00036     underlayConfigurator = UnderlayConfiguratorAccess().get();
00037     bootstrapOracle = BootstrapOracleAccess().get();
00038         
00039     offset = 0;
00040 
00041     // Open file and get size
00042     fd = open(par("traceFile"), O_RDONLY);
00043     
00044     if (!fd) {
00045         throw new cException(("Cant open file " + std::string(par("traceFile")) + 
00046                 std::string(strerror(errno))).c_str());
00047     }
00048 
00049     struct stat filestat;
00050     
00051     if (fstat(fd, &filestat)) {
00052         throw new cException(("Error calling stat: " + std::string(strerror(errno))).c_str());
00053     }
00054     
00055     filesize = filestat.st_size;
00056     remain = filesize;
00057     EV << "Succesfully opened trace file " << std::string(par("traceFile"))
00058        << ". Size: " << filesize;
00059 
00060     nextRead = new cMessage("NextRead");
00061     scheduleAt(0, nextRead);
00062 
00063 }

void GlobalTraceManager::readNextBlock (  )  [protected]

00066 {
00067     double time = -1;
00068     int nodeID;
00069     char* bufend;
00070     int line = 1;
00071 
00072     if ( remain > 0 ) {
00073         // If rest of the file is bigger than maximal chunk size, set chunksize
00074         // to max; the last mapped page is used as margin.
00075         // Else map the whole remainder od the file at a time, no margin is needed
00076         // in this case
00077         chunksize = remain < getpagesize()*readPages ? remain : getpagesize()*readPages;
00078         marginsize = remain == chunksize ? 0 : getpagesize();
00079 
00080         start = (char*) mmap(0, chunksize, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, filesize - remain);
00081         if (start == MAP_FAILED) {
00082             throw new cException(("Error mapping file to memory:" + 
00083                     std::string(strerror(errno))).c_str());
00084         }
00085 
00086         buf = start + offset;
00087         // While the read pointer has not reached the margin, continue parsing
00088         while( buf < start + chunksize - marginsize) { // FIXME: Assuming max line length of getpagesize()
00089 
00090             time = strtod(buf, &bufend);
00091             if (bufend==buf) {
00092                 throw new cException("Error parsing file: Expected time as double");
00093             }
00094             buf = bufend;
00095 
00096             nodeID = strtol(buf, &bufend, 0);
00097             if (bufend==buf) {
00098                 throw new cException("Error parsing file: Expected ID as long int");
00099             }
00100             buf = bufend;
00101 
00102             while( isspace(buf[0]) ) buf++;
00103 
00104             bufend = strchr(buf, '\n');
00105             if (!bufend) {
00106                 throw new cException("Error parsing file: Missing command or no newline at end of line!");
00107             }
00108             bufend[0]='\0';
00109             scheduleNextEvent(time, nodeID, buf, line++);
00110             buf += strlen(buf)+1;
00111 
00112             while( isspace(buf[0]) ) buf++;
00113         }
00114 
00115         // Compute offset for the next read
00116         offset = (buf - start) - (chunksize - marginsize);
00117         remain -= chunksize - marginsize;
00118         munmap( start, chunksize );
00119     }
00120     if (time > 0) {
00121         scheduleAt(time, nextRead);
00122     } else {
00123         // FIXME: Schedule simulation end?
00124     }
00125 }

void GlobalTraceManager::scheduleNextEvent ( double  time,
int  nodeId,
char *  buf,
int  line 
) [protected]

00128 {
00129     GlobalTraceManagerMessage* msg;
00130 
00131     msg = new GlobalTraceManagerMessage(buf);
00132 
00133     msg->setInternalNodeId(nodeId);
00134     msg->setLineNumber(line);
00135     scheduleAt(time, msg);
00136 }

void GlobalTraceManager::createNode ( int  nodeId  )  [protected]

00139 {
00140     check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00141                                                             ->createNode(nodeId);
00142 }

void GlobalTraceManager::deleteNode ( int  nodeId  )  [protected]

00145 {
00146     check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00147                                                             ->deleteNode(nodeId);
00148 }

cGate * GlobalTraceManager::getAppGateById ( int  nodeId  )  [protected]

00211                                                     {
00212     return check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00213                                                                 ->getAppGateById(nodeId);
00214 }


Member Data Documentation

UnderlayConfigurator* GlobalTraceManager::underlayConfigurator [protected]

BootstrapOracle* GlobalTraceManager::bootstrapOracle [protected]

pointer to BootstrapOracle

int GlobalTraceManager::fd [private]

int GlobalTraceManager::filesize [private]

int GlobalTraceManager::chunksize [private]

int GlobalTraceManager::remain [private]

int GlobalTraceManager::marginsize [private]

int GlobalTraceManager::offset [private]

char* GlobalTraceManager::buf [private]

char * GlobalTraceManager::start [private]

const int GlobalTraceManager::readPages = 32 [static, private]

cMessage* GlobalTraceManager::nextRead [private]


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:29 2008 for ITM OverSim by  doxygen 1.5.3