Exemplo n.º 1
0
BOOLEAN mergeRuns(FILE ** sorted, int pagesize, int availableBuffers, FileList currentFiles, int * passes, int * runs, int totalRecordCount){
	RecordHeap rHeap;
	Buffer * bufferNodes;
	int bufferIndex;

/*Determine max files that can be merged in a run*/
/*That is available buffers -1 for the output buffer*/
/*This is also the output buffer indes*/
	int outputBuffIndex = availableBuffers -1;

/*Buffer array (of buffer nodes) where size of which is the number
of buffers available to store in memory*/
	bufferNodes = calloc(availableBuffers, sizeof(Buffer));
	if(!bufferNodes){
		fprintf(stderr, "Error: Failed to allocate buffer array\n");
		return FALSE;
	}

/*Allocate memory for record arrays for each buffer*/
	for(bufferIndex = 0; bufferIndex < availableBuffers; bufferIndex++){
		initBuffer(&bufferNodes[bufferIndex], pagesize);
	}

/*Initialise priority queue
It's size is the amount of files that can be merged in a run*/
/*outputBuffIndex is the last index in the buffer array*/
	if(initHeap(&rHeap, outputBuffIndex * pagesize) == FALSE){
		return FALSE;
	}

/*while more merging required, (more than 1 temporary file)*/
/*go through a pass*/
	while(currentFiles.fileCount > 1){
		int runCount = 0;
		/*Define first file to be the start of the file linked list*/
		FileNode * firstFileForRun = currentFiles.fileHeadNode;

		/*Run file list, is the files to be merged in the next pass*/
		FileList runFileList;/*= calloc(1, sizeof(FileList));*/

		float runsInPassFloat = ((float)currentFiles.fileCount/(float)(availableBuffers-1));
		int runsInPass = ceil(runsInPassFloat);

		initFileList(&runFileList);


/*while still merging required for pass*/
/*go through a run*/
		while(runCount < runsInPass){
			int buffersInUse = 0;
			int bufferIndex = 0;
			int init = 0;
			FileNode * currentRunFile = firstFileForRun;
			FILE * outputFile;
			
/*create new temp file for merge run, written to when output buffer is full*/
			if((outputFile = tmpfile()) == NULL){
				fprintf(stderr, "Error: Failed to create output temporary file for run\n");
				return FALSE;
			}

/*add file pointer to the file list for the next pass*/
			addFile(&runFileList,outputFile);

/*Read in pages from current files to buffers*/
			for(bufferIndex = 0; bufferIndex < outputBuffIndex; bufferIndex++){
				int recordPageIndex;
/*fill buffer with records from file*/
				if(currentRunFile->fp != NULL){
					for(recordPageIndex = 0; recordPageIndex < pagesize; recordPageIndex++){
						/*read in record*/
						Record record;
						if(fread(&record, sizeof(Record), 1, currentRunFile->fp) == 1){
							/*add record to page (records array)*/
							init++;
							if(addRecord(&bufferNodes[bufferIndex], record, pagesize, recordPageIndex) == FALSE)
								return FALSE;
		/*add record index to heap*/
							if(addToHeap(&rHeap, &bufferNodes[bufferIndex], recordPageIndex) == FALSE)
								return FALSE;
						}
		/*else reached file end*/
						else{
							/*temp file will be automatically deleted by the system*/
							fclose(currentRunFile->fp);
							currentRunFile->fp = NULL;
							/*removeFile(currentFiles, currentRunFile);*/
							/*add blank records*/
							/*int blankRecordCount;
							for(blankRecordCount = recordCount; blankRecordCount < pagesize; blankRecordCount++){
								int recordPageIndex = addBlankRecord(&bufferNodes[bufferIndex], pagesize);
								
								if(recordPageIndex < 0)
									return FALSE;
							}*/
							break;
						}
					}
					bufferNodes[bufferIndex].fileNode = currentRunFile;
					buffersInUse++;
					currentRunFile = currentRunFile->nextFileNode;
					if (currentRunFile == NULL)
						break;
				}
				else
					break;
			}
/*set firstFileForRun for next run*/
			firstFileForRun = currentRunFile;

/*while all buffers are not empty (there is still records in pages in
some buffer not including the output buffer)*/
			while(buffersInUse > 0 && rHeap.count > 0){
/*keep getting min record and writing to output buffer*/
/*get smallest record*/
				RecordIndex minIndex = removeMinHeap(&rHeap);
				if(minIndex.guildID == 0)
					return FALSE;
/*move smallest record from main buffer memory to output buffer*/
/*add record to output buffer*/
				addRecord(&bufferNodes[outputBuffIndex],
					minIndex.buff->pageRecords[minIndex.pgIndex], pagesize, bufferNodes[outputBuffIndex].recordCount);
/*remove the same record from original buffer*/
				removeRecord(minIndex.buff, minIndex.pgIndex);
/*if output buffer is full, write page to file*/
				if(bufferNodes[outputBuffIndex].recordCount == pagesize){
/*write page to file*/
					int written;
					written = fwrite(bufferNodes[outputBuffIndex].pageRecords, sizeof(Record),
						pagesize, outputFile);
					if(written !=pagesize){
						fprintf(stderr, "Error: Failed to write to output file, wrote %i records\n",written);
						return FALSE;
					}

					/*clear page in output buffer*/
					clearPage(&bufferNodes[outputBuffIndex], pagesize);
				}

/*if original buffer is empty, read in another page*/
				if(minIndex.buff->recordCount == 0){
					int recordPageIndex;
/*fill buffer with records from file*/
					for(recordPageIndex = 0; recordPageIndex < pagesize; recordPageIndex++){
						Record record;
						if(minIndex.buff->fileNode->fp != NULL){
							if(fread(&record, sizeof(Record), 1, minIndex.buff->fileNode->fp) == 1){
		/*add record to page (records array)*/
								if(addRecord(minIndex.buff, record, pagesize, recordPageIndex) == FALSE)
									return FALSE;
		/*add record index to heap*/
								if(addToHeap(&rHeap, minIndex.buff, recordPageIndex) == FALSE)
									return FALSE;
							}
		/*else reached file end*/
							else{
								/*temp file will be automatically deleted by the system*/
								fclose(minIndex.buff->fileNode->fp);
								minIndex.buff->fileNode->fp = NULL;
								/*removeFile(currentFiles, minIndex.buff->fileNode);*/
								break;
							}
						}
					}
				}
/*if buffer is still empty, then 0 records were read in,
therefore file is empty and the buffer is now free*/
				if(minIndex.buff->recordCount == 0)
					/*decrement buffers in use counter*/
					buffersInUse--;
			}

/*All files for run have been fully read*/
/*Write out records still in output buffer*/
			if(bufferNodes[outputBuffIndex].recordCount > 0){
/*Output buffer page was not full*/
				int i = 0;
				for(i = 0; i < pagesize; i++){
					if(bufferNodes[outputBuffIndex].pageRecords[i].GuildID != 0){
						fwrite(&bufferNodes[outputBuffIndex].pageRecords[i],
							sizeof(Record), 1, outputFile);
						removeRecord(&bufferNodes[outputBuffIndex], i);
					}
				}
			}
			/*Rewind outfile for future merge*/
			rewind(outputFile);
			runCount++;
		}
		/*set runFileListas new current file list*/
		freeFileNode(&currentFiles);
		currentFiles = runFileList;
		*passes = *passes+1;
		*runs = *runs + runCount;
		printf("Pass %i resulted in %i runs\n",*passes,runCount);
	}


/*FileList will contain link to only 1 temporary binary file*/
	if(currentFiles.fileCount != 1){
		fprintf(stderr, "Error: Number of files:%i is invalid\n",currentFiles.fileCount);
		return FALSE;
	}
	*sorted = currentFiles.fileHeadNode->fp;

	/*free allocated memory*/

	for(bufferIndex = 0; bufferIndex < availableBuffers; bufferIndex++){
		freeBuffer(&bufferNodes[bufferIndex]);
	}
	free(bufferNodes);

	freeHeap(&rHeap);

	freeFileNode(&currentFiles);

	/*free(currentFiles);*/

	return TRUE;
}
Exemplo n.º 2
0
int main(int argc, char ** argv)
{
	struct rec * head = NULL;
	int recNum, i, input;
	int menu = 0;
	char name[100];
	char usrOption = 'y';
	double wNum, hNum, bmi;

	printf("How many records would you like to create?\n");
    scanf("%d",&recNum);

    for(i = 0; i < recNum; i++){
    	printf("Name: - ");
    	scanf("%s", name);
    	printf("Weight (kg): - ");
    	scanf("%lf", &wNum);
    	printf("Height (cm): - ");
    	scanf("%lf", &hNum);
    	bmi = calcBmi(wNum, hNum);
    	insertEnd(&head, wNum, hNum, bmi, name, recNum);
    }

    while(menu == 0){
	    printf("\n1. Print Records\n2. Add a record\n3. Send to file\n4. Sort List\n5. Delete a Record\n6. Quit\n");
	    scanf("%d", &input);
	    //If user would like to print the patient records
	    if(input == 1){
	    	printRecs(head);
	    }
	    //Add a new patient record
	    else if(input == 2){
	    	printf("Name: - ");
    		scanf("%s", name);
    		printf("Weight (kg): - ");
	    	scanf("%lf", &wNum);
	    	printf("Height (cm): - ");
	    	scanf("%lf", &hNum);
	    	bmi = calcBmi(wNum, hNum);
	    	recNum++;
	    	addRecord(&head, wNum, hNum, bmi, name, recNum);
	    }
		//Send records to a file
	    else if(input == 3){
			toFile(head);
	    }
	
		//Sorts the list alphabetically
		else if(input == 4){
			printf("This feature is currently in development.\n");
			sortList(&head);
		}

		//If user would like to delete records
		else if(input == 5){
			if(head->next != NULL){
				printf("Which record would you like to delete?\n");
				scanf("%s", name);
			   	removeRecord(&head, name);
			}
			else{
				printf("Sorry! There was a problem with deleting the record!\n");
			}
		}

		//User wishes to quit program
		else if(input == 6){
			printf("Closing Records.\n");
			menu = 1;
		}
		else{
			printf("Sorry! Please enter a valid input.\n");
		}
	}

    destroy(&head);

    return(0);
}
Exemplo n.º 3
0
int clientUploadFile(BIO *conn, char *filename) {

	/* CALCULATE AND STORE ANY RECORDS OF THIS FILE WE NEED
	 * BEFORE UPLOADING IT */

	FILE *ifp = fopen(filename, "rb");
	if ( ifp == NULL )  return NO_SUCH_FILE;
	
	//generate key and iv for encryption
	unsigned char *key = randomBytes(32);
	unsigned char *iv = randomBytes(32);
	
	//encrypt the file
	int status = encryptFile(filename, TEMP_ENCRYPTED_FILENAME, key, iv);
	if(status == -1) {
		fprintf(stderr, "Failed to encrypt %s in clientUploadFile()\n", filename);
		return -1;
	}

	//we need to store NUM_HASHES salts and digests for later verification
	unsigned char *salts[NUM_HASHES];
	unsigned char *hashes[NUM_HASHES];

	for(int i=0; i<NUM_HASHES; ++i) {
		//generate a random salt
		salts[i] = randomBytes(SALT_LENGTH);
		//compute the digest for the file with that salt
		hashes[i] = calculateMD5(TEMP_ENCRYPTED_FILENAME, salts[i], SALT_LENGTH);
		if(hashes[i] == NULL) {
			fprintf(stderr, "Failed to calculate digest in clientUploadFile()\n");
			return -1;
		}
	}
	
	//store all this data for later
	status = addRecord(filename, 0, hashes, salts, key, iv);
	if(status == -1) {
		fprintf(stderr, "addRecord() failed for in clientUploadFile()\n");
		return -1;
	}
	
	//free the memory we allocated above
	for(int i=0; i < NUM_HASHES; ++i) {
		free(salts[i]);
		free(hashes[i]);
	}
	free(key);
	free(iv);

	/* START THE ACTUAL COMMUNICATION WITH THE SERVER */
	
	//send the code which causes the server to call serverUploadFile()
	if(writeInt(conn, UPLOAD_FILE_CODE) == -1) return -1;

	//send the fileSize
	int fileSize = sizeOfFile(TEMP_ENCRYPTED_FILENAME);
	if(writeInt(conn, fileSize) == -1) return -1;

	printf("NOTE: Original size: %f MB. Encrypted size: %f MB.\n", (double)sizeOfFile(filename)/MEGABYTE, (double)fileSize/MEGABYTE);


	//wait for an int telling us the balance owing
	unsigned int fee = readInt(conn);
	if(fee > 0) {
		printf("Purchase %d more cloud dollar(s) to upload this file.\n", fee);
		removeRecord(filename);
		return -1;
	}
	else if(fee < 0) return -1;

	//send the file
	if(writeFile(conn, TEMP_ENCRYPTED_FILENAME, filename) < 1) return -1;
	unlink( TEMP_ENCRYPTED_FILENAME );
	printf("Succesfully uploaded the file.\n");
	return 0;
}