int main() { LinkedList list = newLinkedList(); LinkedList emptyList = newLinkedList(); Student student1 = { "aaa111", 0.0}; Student student2 = { "bbb111", 3.5}; Student student3 = { "ccc111", 2.0}; Student student4 = { "ddd111", 4.0}; Student student5 = { "eee111", 2.5}; insertOrderedLL(list, student1); insertOrderedLL(list, student2); insertOrderedLL(list, student3); insertOrderedLL(list, student4); insertOrderedLL(list, student5); double dHighestGPA = getHighGPA(list->pHead); printf("%.2lf\n\n", dHighestGPA); dHighestGPA = getHighGPA(emptyList->pHead); printf("%.2lf\n\n", dHighestGPA); NodeLL *pLastNode = last(list->pHead); printf("%s\n\n", pLastNode->student.szAbc123Id); pLastNode = last(emptyList->pHead); if(pLastNode == NULL) { printf("Success!\n"); } }
/********************** generateArrival **************************** void getTravelerData(Simulation sim) Purpose: Reads traveler information from file. The values are stored into an event and the event is then inserted into an eventList (linked list) Parameters: O Simulation sim // event list Returns: VIA PARAMETER: 1. Returns a populated event list Notes: 1. Uses interOrderedLL function *******************************************************************/ void generateArrival(Simulation sim) { Event event; // creates a new event to store widgeti // and event information into char szInputBuffer[100]; // input buffer for fgets (entire input line) int iDeltaNextArrival = 0; // next widgets arrival int iTmpTime = 0; // Saves current widget + next widgets arrival time // to get true arrival time for each widget // read text lines containing widget name, step 1 time units, step 2 time units, // and next widget's arrival time in time units until EOF while(fgets(szInputBuffer, 100, stdin) != NULL) { // copies widget information from file and stores it into the newly created widget sscanf(szInputBuffer, "%ld %d %d %d", &event.widget.lWidgetNr // widget name , &event.widget.iStep1tu // widget step 1 time units , &event.widget.iStep2tu // widget step 2 time units , &iDeltaNextArrival); // next widget's arrival time // creates the arrival node for each widget event.iEventType = EVT_ARRIVAL; event.widget.iArrivalTime = iTmpTime; event.iTime = iTmpTime; // inserts the event into the event list insertOrderedLL(sim->eventList, event); iTmpTime += iDeltaNextArrival; // increment iTmpTime by the next widget's arrival time } }
/**************************** seize ****************************** seize(Simulation sim, Queue queueTeller, Server serverTeller) Purpose: Seizes a widget from the queue. Parameters: I Simulation sim // current sim we are running I Queue queueTeller // current queue // either queue1 or queue2 I Server serverTeller // current server // either server1 or server2 Returns: Does not return anything fuctionally, but does insert the newly created server1 or server2 complete event into the linked list. Notes: 1. Uses removeQ function *****************************************************************/ void seize(Simulation sim, Queue queueTeller, Server serverTeller) { QElement fill; // element returned from removeQ Event event; // Server complete event int iWaitTime; // The wait time for each widget in the queue // checks to see if widget is busy if(serverTeller->bBusy == FALSE) { // if not busy // remove widget from queue if(removeQ(queueTeller, &fill)) { iWaitTime = (sim->iClock - fill.iEnterQTime); // wait is equal to current clock time minus the time the widget // enters the system if(sim->bVerbose == TRUE) { printf("%4d %6ld Leave %s Waited: %d\n", sim->iClock, fill.widget.lWidgetNr, queueTeller->szQName, iWaitTime); printf("%4d %6ld Seized %s\n", sim->iClock, fill.widget.lWidgetNr, serverTeller->szServerName); } // set server to be busy serverTeller->bBusy = TRUE; //create completion event for server event.widget = fill.widget; if(sim->cRunType == 'A') { //checks to see whether it is server 1 or 2 to set event type and event time properly if(strcmp(serverTeller->szServerName, "Server 1") == 0) { event.iEventType = EVT_SERVER1_COMPLETE; event.iTime = sim->iClock + fill.widget.iStep1tu; } else if(strcmp(serverTeller->szServerName, "Server 2") == 0) { event.iEventType = EVT_SERVER2_COMPLETE; event.iTime = sim->iClock + fill.widget.iStep2tu; } } else // for alternative b and c - only have 1 server that completes both step1 and step2 { event.iEventType = EVT_SERVER1_COMPLETE; event.iTime = (sim->iClock + fill.widget.iStep1tu + fill.widget.iStep2tu); } queueTeller->lQueueWaitSum += iWaitTime; // add the wait time for each widget to the total wait sum queueTeller->lQueueWidgetTotalCount++; // increment queue count by one each time you seize a widget // inserts the event into the list insertOrderedLL(sim->eventList, event); } } }
/******************** buildGraph ************************************** Graph buildGraph(struct Data dataM[]) Purpose: Builds a graph from an array of edges. The Graph is represented by an array of vertices and a double adjacency list. Parameters: I struct Data dataM[] An array of edges (to, from, path weight) Notes: - The array of edges is terminated by an edge having a from vertex equal to the character '0'. - Normally, this routine checks to make certain that the input did not include a cycle, but since that code wasn't included, the check has been commented out. Returns: Graph - the newly allocated and populated graph. **************************************************************************/ Graph buildGraph(struct Data dataM[]) { int i; int iFrom; int iTo; Edge edge; Graph graph = newGraph(); // Initialize the vertex array to zero bytes. memset(graph->vertexM, '\0', sizeof(Vertex)*MAX_VERTICES); // Go through the array of edges until a From of '\0' is encountered for (i = 0; i < MAX_VERTICES; i++) { if (dataM[i].cFrom == '\0') break; // Find the From vertex. searchVertices returns -1 for not found iFrom = searchVertices(graph, dataM[i].cFrom); if (iFrom == -1) { // not found, so insert the From vertex in the array iFrom = graph->iNumVertices; graph->iNumVertices++; graph->vertexM[iFrom].cLabel = dataM[i].cFrom; } // Find the To vertex. searchVertices returns -1 for not found iTo = searchVertices(graph, dataM[i].cTo); if (iTo == -1) { // not found, so insert the To vertex in the array iTo = graph->iNumVertices; graph->iNumVertices++; graph->vertexM[iTo].cLabel = dataM[i].cTo; } // insert the edge on both the successor and predecessor lists edge.iPath = dataM[i].iPath; edge.iVertex = iTo; insertOrderedLL(&graph->vertexM[iFrom].successorList, edge); edge.iVertex = iFrom; insertOrderedLL(&graph->vertexM[iTo].predecessorList, edge); } // if (!checkCycle(graph)) // ErrExit(ERR_BAD_INPUT, "Cycle in Graph"); return graph; }
/*************************** newListFromInput ********************************** LinkedList newListFromInput() Purpose: Goes through the input file, for each line, creates a widget and an arrival event for that widget and insert it in a list. Parameters: Returns: Functionally: A LinkedList variable populated from the input. Notes: *******************************************************************************/ LinkedList newListFromInput() { /***variables***/ char szInputBuffer[MAX_LINE_SIZE + 1]; Widget widget; Event arrival; LinkedList list; int iClock, iNextArrival, iScanfCnt; //allocate list list = newLinkedList(); iClock = 0; while (fgets(szInputBuffer, MAX_LINE_SIZE, pInputFile) != NULL && iClock <= MAX_ARRIVAL_TIME) //for each line of the input file { if (szInputBuffer[0] == '\n') //if line is empty, ignore { continue; } //populate the widget variable with data from input line and current clock iScanfCnt = sscanf(szInputBuffer, "%ld %d %d %d\n", &(widget.lWidgetNr), &(widget.iStep1tu), &(widget.iStep2tu), &iNextArrival); widget.iArrivalTime = iClock; if (iScanfCnt < 4) //if there's less than 4 tokens in the line { ErrExit(ERR_BAD_INPUT, "%sExpected 4 tokens,received %d successful values\n", szInputBuffer, iScanfCnt); continue; } if (widget.iStep1tu < 0 || widget.iStep2tu < 0 || iNextArrival < 0) //if the values are negative values { ErrExit(ERR_BAD_INPUT, "%sStep1tu, Step2tu, and DeltaArrival cannot be negative values.\n", szInputBuffer, iScanfCnt); continue; } //populate the arrival Event variable arrival.iEventType = EVT_ARRIVAL; arrival.iTime = iClock; arrival.widget = widget; //insert it into the list insertOrderedLL(list, arrival); //increment clock for next input line (next widget) iClock += iNextArrival; } return list; }
/****************************** seize ****************************************** void seize(Simulation sim, Queue queue, Server server) Purpose: Handles the seize event for a given server. In this case, take the top element out of the given queue while updating the queue stats, insert the widget in the given server and mark the server busy, and insert a new event in the simulation's event list representing the widget exiting the server. This function also prints the different steps of the event if verbose mode was activated. Parameters: I Simulation sim Simulation running the event. I/O Queue queue Queue to remove the widget from. I/O Server server Server to insert the widget in, also the server to give its name to the newly created server completion event. Returns: queue parm - the queue to remove the widget from. server parm - the server to insert the widget in. Notes: *******************************************************************************/ void seize(Simulation sim, Queue queue, Server server) { if (server->bBusy == FALSE && queue->pHead != NULL) //if server is free and there's something in the queue { //take top element out of queue and add its wait time to the sum QElement element; removeQ(queue, &element); long lQWaitTime = sim->iClock - element.iEnterQTime; queue->lQueueWaitSum += lQWaitTime; printEvent(sim, " %6d %8ld %s %s%s %ld", sim->iClock, element.widget.lWidgetNr, "Leave", queue->szQName, ", waited", lQWaitTime); //put widget taken out of queue into the server and mark it busy server->widget = element.widget; server->bBusy = TRUE; printEvent(sim, " %6d %8ld %s %s", sim->iClock, element.widget.lWidgetNr, "Seized", server->szServerName); //create a SERVER_COMPLETE event for the widget and place it into the event list Event event; event.widget = server->widget; if (strcmp(server->szServerName, "Server 1") == 0) { if (sim->cRunType == 'A') { //altA only spends step1 in server 1 event.iTime = sim->iClock + event.widget.iStep1tu; } else { //altB and current spend both step 1 and step 2 in server 1 event.iTime = sim->iClock + event.widget.iStep1tu + event.widget.iStep2tu; } event.iEventType = EVT_SERVER1_COMPLETE; } if (strcmp(server->szServerName, "Server 2") == 0) { event.iTime = sim->iClock + event.widget.iStep2tu; event.iEventType = EVT_SERVER2_COMPLETE; } insertOrderedLL(sim->eventList, event); } }