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

 GlobalTraceManager ()
 ~GlobalTraceManager ()
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


Constructor & Destructor Documentation

GlobalTraceManager::GlobalTraceManager (  ) 

00077 {
00078     nextRead = NULL;
00079 }

GlobalTraceManager::~GlobalTraceManager (  ) 

00082 {
00083     cancelAndDelete(nextRead);
00084 }


Member Function Documentation

void GlobalTraceManager::handleMessage ( cMessage *  msg  ) 

00172 {
00173     if (!msg->isSelfMessage()) {
00174         delete msg;
00175         return;
00176     } else if ( msg == nextRead ) {
00177         readNextBlock();
00178         return;
00179     }
00180 
00181     GlobalTraceManagerMessage* traceMsg = check_and_cast<GlobalTraceManagerMessage*>(msg);
00182 
00183     if (strstr(traceMsg->name(), "JOIN") == traceMsg->name()) {
00184         createNode(traceMsg->getInternalNodeId());
00185     } else if (strstr(traceMsg->name(), "LEAVE") == traceMsg->name()) {
00186         deleteNode(traceMsg->getInternalNodeId());
00187     } else if (strstr(traceMsg->name(), "CONNECT_NODETYPES") == traceMsg->name()) {
00188         std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector();
00189 
00190         if (strVec.size() != 3) {
00191             throw new cException("GlobalTraceManager::"
00192                                  "handleMessage(): Invalid command");
00193         }
00194 
00195         int firstNodeType = atoi(strVec[1].c_str());
00196         int secondNodeType = atoi(strVec[2].c_str());
00197 
00198         bootstrapOracle->connectNodeTypes(firstNodeType, secondNodeType);
00199     } else if (strstr(traceMsg->name(), "DISCONNECT_NODETYPES") == traceMsg->name()) {
00200         std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector();
00201 
00202         if (strVec.size() != 3) {
00203             throw new cException("GlobalTraceManager::"
00204                                  "handleMessage(): Invalid command");
00205         }
00206 
00207         int firstNodeType = atoi(strVec[1].c_str());
00208         int secondNodeType = atoi(strVec[2].c_str());
00209 
00210         bootstrapOracle->disconnectNodeTypes(firstNodeType, secondNodeType);
00211     } else if (strstr(traceMsg->name(), "MERGE_BOOTSTRAPNODES") == traceMsg->name()) {
00212         std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector();
00213 
00214         if (strVec.size() != 4) {
00215             throw new cException("GlobalTraceManager::"
00216                                  "handleMessage(): Invalid command");
00217         }
00218 
00219         int toPartition = atoi(strVec[1].c_str());
00220         int fromPartition = atoi(strVec[2].c_str());
00221         int numNodes = atoi(strVec[3].c_str());
00222 
00223         bootstrapOracle->mergeBootstrapNodes(toPartition, fromPartition, numNodes);
00224     } else {
00225         sendDirect(msg, 0, getAppGateById(traceMsg->getInternalNodeId()));
00226         return; // don't delete Message
00227     }
00228 
00229     delete msg;
00230 }

void GlobalTraceManager::initialize ( int  stage  ) 

00040 {
00041     Enter_Method_Silent();
00042 
00043     // Nothing to do for us if there is no traceFile
00044     if (strlen(par("traceFile")) == 0)
00045         return;
00046 
00047     underlayConfigurator = UnderlayConfiguratorAccess().get();
00048     bootstrapOracle = BootstrapOracleAccess().get();
00049 
00050     offset = 0;
00051 
00052     // Open file and get size
00053     fd = open(par("traceFile"), O_RDONLY);
00054 
00055     if (!fd) {
00056         throw new cException(("Cant open file " + std::string(par("traceFile")) +
00057                 std::string(strerror(errno))).c_str());
00058     }
00059 
00060     struct stat filestat;
00061 
00062     if (fstat(fd, &filestat)) {
00063         throw new cException(("Error calling stat: " + std::string(strerror(errno))).c_str());
00064     }
00065 
00066     filesize = filestat.st_size;
00067     remain = filesize;
00068     EV << "Successfully opened trace file " << std::string(par("traceFile"))
00069        << ". Size: " << filesize << endl;
00070 
00071     nextRead = new cMessage("NextRead");
00072     scheduleAt(0, nextRead);
00073 
00074 }

void GlobalTraceManager::readNextBlock (  )  [protected]

Referenced by handleMessage().

00087 {
00088     double time = -1;
00089     int nodeID;
00090     char* bufend;
00091     int line = 1;
00092 
00093     if (remain > 0) {
00094         // If rest of the file is bigger than maximal chunk size, set chunksize
00095         // to max; the last mapped page is used as margin.
00096         // Else map the whole remainder od the file at a time, no margin is needed
00097         // in this case
00098         chunksize = remain < getpagesize()*readPages ? remain : getpagesize()*readPages;
00099         marginsize = remain == chunksize ? 0 : getpagesize();
00100 
00101         start = (char*) mmap(0, chunksize, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, filesize - remain);
00102 
00103         if (start == MAP_FAILED) {
00104             throw new cException(("Error mapping file to memory:" +
00105                     std::string(strerror(errno))).c_str());
00106         }
00107 
00108         buf = start + offset;
00109         // While the read pointer has not reached the margin, continue parsing
00110         while( buf < start + chunksize - marginsize) { // FIXME: Assuming max line length of getpagesize()
00111 
00112             time = strtod(buf, &bufend);
00113             if (bufend==buf) {
00114                 throw new cException("Error parsing file: Expected time as double");
00115             }
00116             buf = bufend;
00117 
00118             nodeID = strtol(buf, &bufend, 0);
00119             if (bufend==buf) {
00120                 throw new cException("Error parsing file: Expected ID as long int");
00121             }
00122             buf = bufend;
00123 
00124             while( isspace(buf[0]) ) buf++;
00125 
00126             bufend = strchr(buf, '\n');
00127             if (!bufend) {
00128                 throw new cException("Error parsing file: Missing command or no newline at end of line!");
00129             }
00130             bufend[0]='\0';
00131             scheduleNextEvent(time, nodeID, buf, line++);
00132             buf += strlen(buf)+1;
00133 
00134             while( isspace(buf[0]) ) buf++;
00135         }
00136 
00137         // Compute offset for the next read
00138         offset = (buf - start) - (chunksize - marginsize);
00139         remain -= chunksize - marginsize;
00140         munmap( start, chunksize );
00141     }
00142 
00143     if (time > 0) {
00144         scheduleAt(time, nextRead);
00145     } else {
00146         // TODO: Schedule simulation end?
00147     }
00148 }

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

Referenced by readNextBlock().

00151 {
00152     GlobalTraceManagerMessage* msg = new GlobalTraceManagerMessage(buf);
00153 
00154     msg->setInternalNodeId(nodeId);
00155     msg->setLineNumber(line);
00156     scheduleAt(time, msg);
00157 }

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

Referenced by handleMessage().

00160 {
00161     check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00162                                                             ->createNode(nodeId);
00163 }

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

Referenced by handleMessage().

00166 {
00167     check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00168                                                             ->deleteNode(nodeId);
00169 }

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

Referenced by handleMessage().

00232                                                     {
00233     return check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00234                                                                 ->getAppGateById(nodeId);
00235 }


Member Data Documentation

pointer to BootstrapOracle

Referenced by handleMessage(), and initialize().

int GlobalTraceManager::fd [private]

Referenced by initialize(), and readNextBlock().

Referenced by initialize(), and readNextBlock().

Referenced by readNextBlock().

Referenced by initialize(), and readNextBlock().

Referenced by readNextBlock().

Referenced by initialize(), and readNextBlock().

char* GlobalTraceManager::buf [private]

Referenced by readNextBlock().

char * GlobalTraceManager::start [private]

Referenced by readNextBlock().

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

Referenced by readNextBlock().

cMessage* GlobalTraceManager::nextRead [private]


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:07 2008 for ITM OverSim by  doxygen 1.5.5