/* * createTree * Function: Uses a CharCounts list to create a min-heap Huffman binary tree * Parameters: The CharCounts list to use * Return: The min-heap Huffman binary tree */ EncodingTree * createTree(CharCounts * counts) { EncodingTree * root; TreeQueue * queue; TreeQueue * toAdd; EncodingTree * temp1; EncodingTree * temp2; int nodeCount; CharCounts * tempCount; root = NULL; queue = NULL; toAdd = NULL; temp1 = NULL; temp2 = NULL; nodeCount = 0; tempCount = NULL; /* Insert all CharCounts into the TreeQueue (sorted least to greatest) */ tempCount = counts; while(tempCount != NULL) { toAdd = createBranch(tempCount); tempCount = tempCount->next; queue = insertInQueue(queue, toAdd); } /*printQueue(queue);*/ toAdd = NULL; /* * Remove from the TreeQueue, TWO AT A TIME, to create a singular binary tree, * and insert back into sorted queue accordingly * Continue until there is nothing left in the queue */ while(isEmpty(queue) == 0) { /*printf("boom\n");*/ if(toAdd != NULL) { queue = insertInQueue(queue, toAdd); } /* Remove two from queue */ temp1 = queue->root; /*printf("%c%d\n\nQueue1\n", temp1->letter, temp1->count);*/ /*printQueue(queue);*/ queue = queue->next; /*printf("Queue2\n");*/ /*printQueue(queue);*/ temp2 = queue->root; /*printf("%c%d\n\n", temp2->letter, temp2->count);*/ queue = queue->next; /*printQueue(queue);*/ temp2 = insertInTree(temp2, temp1); toAdd = createBranchFromTree(temp2); } root = toAdd->root; return(root); }
int Cache::beginSegment(TreeDescriptor treeIdx, int nid, int idx, char *start, int startSize, char *end, int endSize, char *dim, int dimSize, char *shape, int shapeSize, char *data, int dataSize, int writeMode) { int retIdx; int status = dataManager.beginSegment(treeIdx, nid, idx, start, startSize, end, endSize, dim, dimSize, shape, shapeSize, data, dataSize, &retIdx); if(!(status & 1)) return status; //if WRITE_THROUGH or WRITE_BUFFER, segments are written in the tree only when they have been filled if(writeMode == WRITE_BACK) { insertInQueue(treeIdx, nid, FLUSH_BEGIN_SEGMENT, retIdx); }//If writeMode == 0, this segment is being copied from tree, and therefore requires no attention if(writeMode == UPDATE_FLUSH) { insertInQueue(treeIdx, nid, FLUSH_UPDATE_SEGMENT, retIdx); }//If writeMode == 0, this segment is being copied from tree, and therefore requires no attention return 1; }
int Cache::beginTimestampedSegment(TreeDescriptor treeIdx, int nid, int idx, int numItems, char *shape, int shapeSize, char *data, int dataSize, _int64 start, _int64 end, char *dim, int dimSize, int writeMode) { int retIdx; int status = dataManager.beginTimestampedSegment(treeIdx, nid, idx, numItems, shape, shapeSize, data, dataSize, start, end, dim, dimSize, &retIdx); if(!(status & 1)) return status; //if WRITE_THROUGH or WRITE_BUFFER, segments are written in the tree only when they have been filled if(writeMode == WRITE_BACK) { insertInQueue(treeIdx, nid, FLUSH_BEGIN_SEGMENT, retIdx); } return 1; }
int Cache::putRecord(TreeDescriptor treeIdx, int nid, char dataType, int numSamples, char *data, int size, int writeMode) { int status = dataManager.setData(treeIdx, nid, dataType, numSamples, data, size); if(!(status & 1)) return status; if(writeMode == WRITE_THROUGH || writeMode == WRITE_BUFFER) { if(size == 0) treeWriter.addDelete(treeIdx, nid); else treeWriter.addPutRecord(treeIdx, nid); } else //WRITE_BACK { insertInQueue(treeIdx, nid, FLUSH_PUT_RECORD, 0); } return 1; }
int Cache::appendRow(TreeDescriptor treeIdx, int nid, int *bounds, int boundsSize, char *data, int dataSize, _int64 timestamp, int writeMode) { static int count; int status, segmentFilled, retIdx; bool newSegmentCreated; status = dataManager.appendRow(treeIdx, nid, bounds, boundsSize, data, dataSize, timestamp, &segmentFilled, &retIdx, &newSegmentCreated); if((status & 1)) { if(writeMode == WRITE_THROUGH && segmentFilled) treeWriter.addPutTimestampedSegment(treeIdx, nid, retIdx, 0); else if((writeMode == WRITE_BUFFER &&segmentFilled)|| writeMode == WRITE_LAST) { //printf("APPEND %d\n", count++); treeWriter.addPutTimestampedSegment(treeIdx, nid, 0, 1); } else if(writeMode == WRITE_BACK && newSegmentCreated) insertInQueue(treeIdx, nid, FLUSH_BEGIN_SEGMENT, retIdx); } return status; }
int main(int argc, char *argv[]) { DIR *dir; //directory stream FILE *file; //file stream struct dirent *ent; // directory entry structure char *line = NULL; // pointer to size_t len = 1000; //the length of bytes getline will allocate size_t read; unsigned int iThread = 0; unsigned int threadCount = 0; char full_filename[256]; //will hold the entire file name to read int rc; pthread_t threads[MAX_NUM_THREADS]; pthread_attr_t attr; // check the arguments if(argc < 2) { printf("Not enough arguments supplied\n"); return -1; } if(argc > 2) { printf("Too many arguments supplied\n"); return -1; } if(0 != pthread_mutex_init(&fileQueueUpdateLock, NULL)){ fprintf(stderr, "\n Mutex init failed !!"); } /* Threads will be created with joinable attribute. So that each thread can finish before the we exit */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // try to open the directory given by the argument if ((dir = opendir (argv[1])) != NULL) { /* print all the files and directories within directory */ while ((ent = readdir (dir)) != NULL) { // Check if the list is a regular file if(ent->d_type == DT_REG) { //printf ("%s\n", ent->d_name); // Create the absolute path of the filename //snprintf(full_filename, sizeof full_filename, "./%s%s\0", argv[1], ent->d_name); //snprintf(arguments->filename, sizeof(full_filename), "./%s%s\0", argv[1], ent->d_name); snprintf(full_filename, sizeof(full_filename), "./%s%s\0", argv[1], ent->d_name); //fprintf(stderr, "\n (%s) ", full_filename); //Insert the file names in the global file list //Threads will get their work from this list if(NULL != globalFileQueue) { insertInQueue(globalFileQueue, full_filename); } else{ globalFileQueue = createQueue(full_filename); } //sprintf(arguments->filename, "./%s%s\0", argv[1], ent->d_name); // open the file /* file = fopen(full_filename, "r"); // file was not able to be open if (file != NULL) { // Print out each line in the file while ((read = getline(&line, &len, file)) != -1) { printf("Retrieved line of length %d:\n", read); printf("%s", line); } fclose(file); } */ } } /* Only MAX_NUM_THREADS of threads are created. Each thread may or may not process multiple files from the global list created */ for( iThread = 0; iThread < MAX_NUM_THREADS; iThread++) { struct threadArguments *arguments = (struct threadArguments *)malloc(sizeof(struct threadArguments)); arguments->tid = iThread; rc = pthread_create(&threads[iThread], &attr, PrintData, (void *)arguments); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } // Close the directory structure closedir (dir); } else { /* could not open directory */ perror (""); return -1; } pthread_attr_destroy(&attr); /* Wait for all threads to finish processing its work */ for( iThread = 0; iThread < MAX_NUM_THREADS; iThread++) { pthread_join(threads[iThread], NULL); } pthread_mutex_destroy(&fileQueueUpdateLock); pthread_exit(NULL); return 0; }
/*Round-Robin Function Variable Definition: -- stream: file stream for schedule result -- header: header pointer of process_info structure -- signal: signal that decide process priority Return value: NULL */ void roundRobin(FILE *stream, PROCESS_INFO *header, const char signal){ STATUS_QUEUES *schedule = initStatusQueues(header, signal); //status_queues structure node PROCESS_INFO *temp; //process_info structure temp PROCESS_INFO *temp_next; //process_info structure temp_next int time_count = 0; //total time int running_count = 0; //running time //Start schedule while (true){ //Running queue has element if (notEmptyQueue(schedule->queues[3])){ //Delete the first element in running queue temp = deleteInQueue(schedule->queues[3]); //Process need to handle I/O if (temp->remain_time == temp->cpu_time/2){ insertInQueue(schedule->queues[1], temp, 'O'); } //Process has finished else if (temp->remain_time == 0){ temp->finish_time = time_count; insertInQueue(schedule->queues[4], temp, 'I'); } //Process has running QUANTUM time else if (temp->running_time == QUANTUM_SIZE){ insertInQueue(schedule->queues[2], temp, signal); } //Process to running queue else{ insertInQueue(schedule->queues[3], temp, signal); } } //Get arrival process(es) and insert them to ready queue while (notEmptyQueue(schedule->queues[0]) && (schedule->queues[0]->next->arrival_time == 0)){ temp = deleteInQueue(schedule->queues[0]); insertInQueue(schedule->queues[2], temp, signal); } //Get process(es) has handle I/O finish and insert them to ready queue while (notEmptyQueue(schedule->queues[1]) && (schedule->queues[1]->next->io_time == 0)){ temp = deleteInQueue(schedule->queues[1]); insertInQueue(schedule->queues[2], temp, signal); } //Get the first or second element in ready queue and insert it to running queue if (notEmptyQueue(schedule->queues[2]) && !notEmptyQueue(schedule->queues[3])){ //Delete the first element in ready queue temp = deleteInQueue(schedule->queues[2]); //Process NOT run QUANTUM time just now if (temp->running_time != QUANTUM_SIZE){ insertInQueue(schedule->queues[3], temp, signal); } //Only one process in ready queue else if (!notEmptyQueue(schedule->queues[2])){ temp->running_time = 0; insertInQueue(schedule->queues[3], temp, signal); } //Process has ran QUANTUM time should queue again else{ temp_next = deleteInQueue(schedule->queues[2]); insertInQueue(schedule->queues[3], temp_next, signal); insertInQueue(schedule->queues[2], temp, signal); } } //Test whether scheduler is finished if (emptyStatusQueues(schedule)){ break; } else if (notEmptyQueue(schedule->queues[3])){ running_count++; } //Output schedule snapshot printQueuesSnapshot(stream, schedule, time_count); //Plus total time time_count++; } //Output schedule statistics printQueuesStatistics(stream, schedule, time_count, running_count); //Free all elements in queues clearStatusQueues(schedule); return; }