Exemple #1
0
/*
  This function copies the contents of the disk starting from <startBlock> to <endBlock> to a unix file.
*/
void copyBlocksToFile (int startblock,int endblock,char *filename)
{
	int fd;
	fd = open(DISK_NAME, O_RDONLY, 0666);
	if(fd < 0){
	  printf("Unable to Open Disk File!\n");
	  return;
	}
	close(fd);
	int i,j;
	FILE *fp;
	expandpath(filename);
	fp = fopen(filename,"w");
	if(fp == NULL)
	{
		printf("File \'%s\' not found!\n", filename);
	}
	else
	{
		for(i = startblock; i <= endblock; i++)
		{
			emptyBlock(TEMP_BLOCK);
			readFromDisk(TEMP_BLOCK,i);
			for(j=0;j<BLOCK_SIZE;j++)
			{
				fprintf(fp,"%s\n",disk[TEMP_BLOCK].word[j]);
			}
		}
		fclose(fp);
	}

}
Exemple #2
0
/*
  This function loads the OS startup code specified by the first arguement to its appropriate location on disk.
  The code is first copied to memory copy. If this copying proceeds properly then the memory copy is committed to the disk.
*/
int loadOSCode(char* fileName){

	emptyBlock(TEMP_BLOCK);
	writeToDisk(TEMP_BLOCK,OS_STARTUP_CODE);
	expandpath(fileName);
	FILE* fp = fopen(fileName, "r");
	int i,j;
	if(fp == NULL)
	{
		printf("File \'%s\' not found.\n", fileName);
		return -1;
	}

	for(i=0;i<OS_STARTUP_CODE_SIZE;i++)
	{
		j = writeFileToDisk(fp, OS_STARTUP_CODE + i, ASSEMBLY_CODE);
		if (j != 1)
			break;
	}
	if(j==1)
	{
		printf("OS Code exceeds %d block\n",OS_STARTUP_CODE_SIZE);
		deleteOSCodeFromDisk();
		//emptyBlock(TEMP_BLOCK);
		//writeToDisk(TEMP_BLOCK,OS_STARTUP_CODE);
	}
	close(fp);
	return 0;
}
Exemple #3
0
/*
  This function deletes the Interrupt <intNo> from the disk.
*/
int deleteIntCode(int intNo)
{
	emptyBlock(TEMP_BLOCK);
	int i;
	for (i=0;i<INT1_SIZE; i++)
		writeToDisk(TEMP_BLOCK,((intNo - 1) * INT1_SIZE)  + INT1 + i);
	return 0;
}
Exemple #4
0
/*
  This function deletes the Exception Handler from the disk.
*/
int deleteExHandlerFromDisk()
{
	emptyBlock(TEMP_BLOCK);
	int i;
	for (i=0;i<EX_HANDLER_SIZE; i++)
		writeToDisk(TEMP_BLOCK,EX_HANDLER + i);
	return 0;
}
Exemple #5
0
/*
  This function deletes the OS code from the disk.
*/
int deleteOSCodeFromDisk()
{
	emptyBlock(TEMP_BLOCK);
	int i;
	for (i=0;i<OS_STARTUP_CODE_SIZE; i++)
		writeToDisk(TEMP_BLOCK,OS_STARTUP_CODE+i);
	return 0;
}
Exemple #6
0
/*
  This function deletes the Timer Interrupt from the disk.
*/
int deleteTimerFromDisk()
{
	emptyBlock(TEMP_BLOCK);
	int i;
	for (i=0;i<TIMERINT_SIZE; i++)
		writeToDisk(TEMP_BLOCK,TIMERINT+i);
	return 0;
}
Exemple #7
0
/*
  This function frees the blocks specified by the block number present in the first arguement. The second arguement is the size
  of the first argument.
  The memory copy is not committed.
*/
void FreeUnusedBlock(int *freeBlock, int size){
	int i=0;
	for( i = 0 ; i < size && freeBlock[i] != -1 && freeBlock[i] != 0; i++){
		//printf("Block Num = %d\nLocation = %d", freeBlock[i],freeBlock[i] % BLOCK_SIZE );
		storeValue( disk[DISK_FREE_LIST + freeBlock[i] / BLOCK_SIZE].word[freeBlock[i] % BLOCK_SIZE] , 0 );
		emptyBlock(TEMP_BLOCK);
		writeToDisk(TEMP_BLOCK,freeBlock[i]);
	}
}
Exemple #8
0
/*
  This function deletes the INIT code from the disk.
*/
int deleteINITFromDisk()
{
	emptyBlock(TEMP_BLOCK);
	int i;
	for (i=0; i<NO_OF_INIT_BLOCKS; i++)
		writeToDisk(TEMP_BLOCK,INIT_BASIC_BLOCK+i);

	//writeToDisk(TEMP_BLOCK,INIT_BASIC_BLOCK);
	//writeToDisk(TEMP_BLOCK,INIT_BASIC_BLOCK+1);
	//writeToDisk(TEMP_BLOCK,INIT_BASIC_BLOCK+2);
	return 0;
}
Exemple #9
0
/*
  This function displays the content of the files stored in the disk.
*/
void displayFileContents(char *name)
{
	int fd;
	fd = open(DISK_NAME, O_RDONLY, 0666);
	if(fd < 0){
	  printf("Unable to Open Disk File!\n");
	  return;
	}

	close(fd);
	int i,j,k,l,flag=0,locationOfFat;
	int blk[512];

	for(i=0;i<511;i++)
		blk[i] = 0;

	locationOfFat = CheckRepeatedName(name);
	if(locationOfFat >= FAT_SIZE){
		printf("File \'%s\' not found!\n",name);
		return;
	}


	getDataBlocks(blk,locationOfFat);

	k = 1;
	while (blk[k] > 0)
	{
		emptyBlock(TEMP_BLOCK);
		readFromDisk(TEMP_BLOCK,blk[k]);
		for(l=0;l<BLOCK_SIZE;l++)
		{
			if(strcmp(disk[TEMP_BLOCK].word[l],"\0")!=0)
				printf("%s   \n",disk[TEMP_BLOCK].word[l]);
		}
		//printf("next block\n");
		emptyBlock(TEMP_BLOCK);
		k++;
	}
}
Exemple #10
0
/*
  This function returns the basic block entry(pass by pointer) corresponding to the address specified by the second arguement.
  Third argument specifies the type of file (assembly code or data file)
  NOTE: locationOfFat - relative word address of the name field in the fat.
*/
int getDataBlocks(int *basicBlockAddr, int locationOfFat)
{

	int i,a;
	basicBlockAddr[0] = getValue(disk[FAT + locationOfFat / BLOCK_SIZE].word[locationOfFat % BLOCK_SIZE + FATENTRY_BASICBLOCK]);
	emptyBlock(TEMP_BLOCK);
	//printf("Basic Block = %d\n",basicBlockAddr[0]);
	readFromDisk(TEMP_BLOCK,basicBlockAddr[0]);

	i = 0;
	a = getValue(disk[TEMP_BLOCK].word[i]);
	while ((a > 0) && i < MAX_DATAFILE_SIZE)
	{
		//printf("%d %d\t",i+1,a);
		basicBlockAddr[i+1] = a;
		i++;
		a = getValue(disk[TEMP_BLOCK].word[i]);
	}

	return 0;
}
Exemple #11
0
/*
  This function loads a data file to the disk.
*/
int loadDataToDisk(char *name)
{
	FILE *fileToBeLoaded;
	int freeBlock[MAX_DATAFILE_SIZE_BASIC];
	int i,j,k,num_of_chars=0,num_of_blocks_reqd=0,file_size=0,num_of_words=0;
	for(i=0;i<MAX_DATAFILE_SIZE_BASIC;i++)
		freeBlock[i]=-1;
	char c='\0',*s;
	char filename[50],buf[16];
	s = strrchr(name,'\\');
	if(s!=NULL)
		strcpy(filename,s+1);
	else
		strcpy(filename,name);

	filename[15]='\0';
	addext(filename,".dat");

	expandpath(name);
	fileToBeLoaded = fopen(name, "r");
	if(fileToBeLoaded == NULL)
	{
		printf("File \'%s\' not found.!\n", name);
		return -1;
	}
	if(fileToBeLoaded == NULL)
	{
		printf("The file could not be opened!");
		return -1;
	}

	fseek(fileToBeLoaded, 0L, SEEK_END);

	num_of_chars = ftell(fileToBeLoaded);

	fseek(fileToBeLoaded,0,SEEK_SET);
	while(1)
	{
		fgets(buf,16,fileToBeLoaded);
		num_of_words++;
		if(feof(fileToBeLoaded))
			break;
	}
	num_of_blocks_reqd = (num_of_words/512) + 1;
	//printf("\n Chars = %d, Words = %d, Blocks(chars) = %d, Blocks(words) = %d",num_of_chars,num_of_words,num_of_blocks_reqd,(num_of_words/512));
	if(num_of_blocks_reqd > MAX_DATAFILE_SIZE)
	{
		printf("The size of file exceeds %d blocks",MAX_DATAFILE_SIZE);
		return -1;
	}

	fseek(fileToBeLoaded,0,SEEK_SET);

	for(i = 0; i < num_of_blocks_reqd + 1; i++)
	{
		if((freeBlock[i] = FindFreeBlock()) == -1){
				printf("not sufficient space in disk to hold a new file.\n");
				FreeUnusedBlock(freeBlock, MAX_DATAFILE_SIZE_BASIC);
				return -1;
			}
	}
	i = CheckRepeatedName(filename);
	if( i < FAT_SIZE )
	{
		printf("Disk already contains the file with this name. Try again with a different name.\n");
		FreeUnusedBlock(freeBlock, MAX_DATAFILE_SIZE_BASIC);
		return -1;
	}

	k = FindEmptyFatEntry();
	if( k == -1 )
	{
		FreeUnusedBlock(freeBlock, MAX_DATAFILE_SIZE_BASIC);
		printf("No free FAT entry found.\n");
		return -1;
	}


	for(i = DISK_FREE_LIST ;i < DISK_FREE_LIST + NO_OF_FREE_LIST_BLOCKS; i++)		//updating disk free list in disk
		writeToDisk(i, i);
	emptyBlock(TEMP_BLOCK);				//note:need to modify this

	for( i = 1 ; i < MAX_DATAFILE_SIZE_BASIC ; i++ )
	{
		storeValue(disk[TEMP_BLOCK].word[i-1],freeBlock[i]);
	}
	writeToDisk(TEMP_BLOCK,freeBlock[0]);

	for(i=0;i<num_of_blocks_reqd;i++)
	{
		j = writeFileToDisk(fileToBeLoaded, freeBlock[i+1], DATA_FILE);
		file_size++;
	}


	AddEntryToMemFat(k, filename, file_size * BLOCK_SIZE, freeBlock[0]);
	for(i = FAT; i < FAT + NO_OF_FAT_BLOCKS ; i++){
		writeToDisk(i,i);				//updating disk fat entry note:check for correctness
	}

      close(fileToBeLoaded);
      return 0;

}
Exemple #12
0
/*
  This function loads the executable file corresponding to the first arguement to an appropriate location on the disk.
  This function systematically uses the above functions to do this action.
*/
int loadExecutableToDisk(char *name)
{
	FILE *fileToBeLoaded;
	int freeBlock[SIZE_EXEFILE_BASIC];
	int i,j,k,l,file_size=0,num_of_lines=0,num_of_blocks_reqd=0;
	for(i=0;i<SIZE_EXEFILE_BASIC;i++)
		freeBlock[i]=-1;
	char c='\0',*s;
	char filename[50];
	s = strrchr(name,'\\');
	if(s!=NULL)
		strcpy(filename,s+1);
	else
		strcpy(filename,name);

	filename[15]='\0';

	addext(filename,".xsm");

	expandpath(name);
	fileToBeLoaded = fopen(name, "r");
	if(fileToBeLoaded == NULL){
	    printf("File %s not found.\n", name);
	    return -1;
	  }
	if(fileToBeLoaded == NULL){
		printf("The file could not be opened");
		return -1;
	}

	while(c!=EOF)
	{
		c=fgetc(fileToBeLoaded);
		if(c=='\n')
			num_of_lines++;
	}

	num_of_blocks_reqd = (num_of_lines / (BLOCK_SIZE/2)) + 1;

	if(num_of_blocks_reqd > SIZE_EXEFILE)
	{
		printf("The size of file exceeds %d blocks",SIZE_EXEFILE);
		return -1;
	}

	fseek(fileToBeLoaded,0,SEEK_SET);

	for(i = 0; i < num_of_blocks_reqd + 1; i++)
	{
		if((freeBlock[i] = FindFreeBlock()) == -1){
				printf("Insufficient disk space!\n");
				FreeUnusedBlock(freeBlock, SIZE_EXEFILE_BASIC);
				return -1;
			}
	}
	i = CheckRepeatedName(filename);
	if( i < FAT_SIZE ){
		printf("Disk already contains the file with this name. Try again with a different name.\n");
		FreeUnusedBlock(freeBlock, SIZE_EXEFILE_BASIC);
		return -1;
	}

	k = FindEmptyFatEntry();
	if( k == -1 ){
		FreeUnusedBlock(freeBlock, SIZE_EXEFILE_BASIC);
		printf("No free FAT entry found.\n");
		return -1;
	}


	for(i = DISK_FREE_LIST ;i < DISK_FREE_LIST + NO_OF_FREE_LIST_BLOCKS; i++)		//updating disk free list in disk
		writeToDisk(i, i);
	emptyBlock(TEMP_BLOCK);				//note:need to modify this

	for( i = 1 ; i < SIZE_EXEFILE_BASIC ; i++ )
	{
		storeValue(disk[TEMP_BLOCK].word[i-1],freeBlock[i]);
	}
	writeToDisk(TEMP_BLOCK,freeBlock[0]);

	for(i=0;i<num_of_blocks_reqd;i++)
	{
		j = writeFileToDisk(fileToBeLoaded, freeBlock[i+1], ASSEMBLY_CODE);
		file_size++;
	}



	AddEntryToMemFat(k, filename, file_size * BLOCK_SIZE, freeBlock[0]);
	for(i = FAT; i < FAT + NO_OF_FAT_BLOCKS ; i++){
		writeToDisk(i,i);
	}

      close(fileToBeLoaded);
      return 0;
}
uint mergeElimination(int &input, int &output, block_t *buffer, uint memSize, uint segsToMerge, uint *blocksLeft, uint segmentSize, uint firstSegOffset, unsigned char field, bool lastPass, bool lastMergeOfPass, uint *nunique) {
    uint ios = 0;
    block_t *bufferOut = buffer + memSize;
    uint blocksWritten = 0;
    uint sizeOfLastSeg;
    if (lastMergeOfPass) {
        sizeOfLastSeg = blocksLeft[segsToMerge - 1] + 1;
    }
    // holds the last unique value written to the output
    record_t *lastRecordAdded = NULL;

    recordPtr *nextRecord = (recordPtr*) malloc(segsToMerge * sizeof (recordPtr));
    for (uint i = 0; i < segsToMerge; i++) {
        nextRecord[i].block = i;
        nextRecord[i].record = 0;
    }
    emptyBlock(bufferOut);
    (*bufferOut).blockid = 0;

    uint segsToMergeCopy = segsToMerge;
    while (segsToMergeCopy != 0) {
        uint i;
        for (i = 0; i < segsToMerge; i++) {
            if (buffer[i].valid) {
                break;
            }
        }
        record_t minRec = getRecord(buffer, nextRecord[i]);
        uint minBuffIndex = i;

        for (uint j = i + 1; j < segsToMerge; j++) {
            if (buffer[j].valid && compareRecords(getRecord(buffer, nextRecord[j]), minRec, field) < 0) {
                minRec = getRecord(buffer, nextRecord[j]);
                minBuffIndex = j;
            }
        }

        if (!lastPass) {
            (*bufferOut).entries[(*bufferOut).nreserved++] = minRec;
        } else {
            if (!lastRecordAdded) {
                (*bufferOut).entries[(*bufferOut).nreserved++] = minRec;
                (*nunique) += 1;
                lastRecordAdded = (record_t*) malloc(sizeof (record_t));
                memcpy(lastRecordAdded, &minRec, sizeof (record_t));
            } else {
                if (compareRecords(*lastRecordAdded, minRec, field) != 0) {
                    (*bufferOut).entries[(*bufferOut).nreserved++] = minRec;
                    (*nunique) += 1;
                    memcpy(lastRecordAdded, &minRec, sizeof (record_t));
                }
            }
        }

        if ((*bufferOut).nreserved == MAX_RECORDS_PER_BLOCK) {
            ios += writeBlocks(output, bufferOut, 1);
            (*bufferOut).blockid += 1;
            blocksWritten += 1;
            emptyBlock(bufferOut);
        }

        incr(nextRecord[minBuffIndex]);

        if (nextRecord[minBuffIndex].record == 0) {
            nextRecord[minBuffIndex].block -= 1;
            if (blocksLeft[minBuffIndex] > 0) {
                uint blockOffset;
                if (lastMergeOfPass && minBuffIndex == segsToMerge - 1) {
                    blockOffset = firstSegOffset + segmentSize * minBuffIndex + sizeOfLastSeg - blocksLeft[minBuffIndex];
                } else {
                    blockOffset = firstSegOffset + segmentSize * minBuffIndex + segmentSize - blocksLeft[minBuffIndex];
                }
                ios += preadBlocks(input, buffer + minBuffIndex, blockOffset, 1);
                blocksLeft[minBuffIndex] -= 1;
                if (!buffer[minBuffIndex].valid) {
                    segsToMergeCopy -= 1;
                }
            } else {
                buffer[minBuffIndex].valid = false;
                segsToMergeCopy -= 1;
            }
        } else {
            if (!getRecord(buffer, nextRecord[minBuffIndex]).valid) {
                buffer[minBuffIndex].valid = false;
                segsToMergeCopy -= 1;
            }
        }
    }
    free(nextRecord);
    if (lastRecordAdded) {
        free(lastRecordAdded);
    }

    if ((*bufferOut).nreserved != 0) {
        ios += writeBlocks(output, bufferOut, 1);
        (*bufferOut).blockid += 1;
        blocksWritten += 1;
    }

    if (!lastPass && !lastMergeOfPass) {
        for (uint i = 0; i < segmentSize * segsToMerge - blocksWritten; i++) {
            ios += writeBlocks(output, buffer, 1);
        }
    }
    return ios;
}
Exemple #14
0
void MergeJoin (char *infile1, char *infile2, unsigned char field, block_t *buffer, unsigned int nmem_blocks, char *outfile, unsigned int *nres, unsigned int *nios){
    //memSize of buffer is -2 cause 2 last blocks is used for, one reading block from big file and two writing to output
    int memSize = nmem_blocks - 2;
    //get sizes of files
    int infile1Size = getSize(infile1);
    int infile2Size = getSize(infile2);

    unsigned int noneed1=0, noneed2=0, ios=0;
    *nres = 0;
    *nios = 0;

    FILE *out = fopen(outfile, "ab");

    char outfile1[] = "outfile1.bin";
    char outfile2[] = "outfile2.bin";



    MergeSort(infile1, 1, buffer, nmem_blocks, outfile1, &noneed1, &noneed2, &ios);
    (*nios) += ios;

    MergeSort(infile2, 1, buffer, nmem_blocks, outfile2, &noneed1, &noneed2, &ios);
    (*nios) += ios;

    //if file1 is bigger switch files cause next we assume that file1 is the small one.
    if(infile1Size > infile2Size){
        char temp0 = outfile1[7];
        outfile1[7] = outfile2[7];
        outfile2[7] = temp0;
        int temp = infile1Size;
        infile1Size = infile2Size;
        infile2Size = temp;
    }
    FILE *input1 = fopen(outfile1, "rb");
    FILE *input2 = fopen(outfile2, "rb");
    ////printfile(outfile1);
    ////printfile(outfile2);

    block_t *bigFileBlock = buffer + memSize;
    block_t *outputBlock = buffer + memSize + 1;
    (*outputBlock).blockid = 0;
    //offset that changes every time we need new block from big file to check
    int bigFileBlockOffset=0;
    //counts the records of buffer that has same value of a record of bigFileBlock
    int countSameBufferEntries=0;
    //number of blocks in big file. Useful to end the main loop.
    int blocks = infile2Size - 1;
    //printf("%d", blocks);
    //this will represent the id of the first block of the buffer
    int firstBlockId = 0;
    int lastBlockId = memSize-1;
    //at first we read first blocks of small and big file so we have something to compare in first loop
    (*nios) += readBuffer(buffer, input1, 0, memSize);
    (*nios) += readBlock(bigFileBlock, input2, 0);
    recordPos bufferRecPos = getRecordPos(0);
    record_t tempBufferRec;
    int tempBufferBlock=0;
    record_t bigFileBlockRec;
    while(blocks>0){
        /*
        General:
            if(bufferRecPos.block%memSize==firstBlockId%memSize)
                this condition checks if we have reached i circle in the buffer.

            firstBlockId%memSize
                defines the first block of the buffer and makes it easy to replace it with another block if necessary with:
                    buffer + firstBlockId%memSize



        */

        for(int blockEntrie=0; blockEntrie<MAX_RECORDS_PER_BLOCK; blockEntrie++){

            bigFileBlockRec = (*bigFileBlock).entries[blockEntrie];

            if(compareRecords(tempBufferRec, bigFileBlockRec, field)==0){
                //Here we  have to go back to the block and record of tempBufferRec.
                for(int i=0; i<countSameBufferEntries; i++){
                    decr(bufferRecPos);
                    ////printf("%d\n", bufferRecPos.block);
                }
                int i=0;//keeps i for load2
                int load, load2;
                if(countSameBufferEntries/memSize > memSize){
                    load = memSize;
                    load2=0;
                }else{
                    load = countSameBufferEntries/memSize;
                    load2 = countSameBufferEntries%memSize;
                }
                for( ;i<load; i++){
                    (*nios) += readBlock(buffer + (tempBufferBlock + i) % memSize, input1, tempBufferBlock + i);
                }
                if(load2!=0){//we have to read one more block.
                    (*nios) += readBlock(buffer + (tempBufferBlock + i) % memSize, input1, tempBufferBlock + i);
                }
                //return to firstBlockID and lastBlockID their previous values
                firstBlockId = tempBufferBlock ;
                lastBlockId = firstBlockId + memSize - 1;
            }

            while(compareRecords(getRecord(buffer, bufferRecPos), bigFileBlockRec, field) < 0){
                //Here we have to pass the records in the small file that are smaller than the bigFileRec
                incr(bufferRecPos);
                if (bufferRecPos.record == 0) {
                     if(bufferRecPos.block%memSize==firstBlockId%memSize){
                        if (lastBlockId < infile1Size - 1) {
                            (*nios) += readBlock(buffer + firstBlockId%memSize, input1, lastBlockId + 1);
                            firstBlockId += 1;
                            lastBlockId += 1;
                        }else{
                            blocks=0;//No point to continue merging as all next records are greater than the last of buffer.
                            break;
                        }
                    }
                }
            }

            if(compareRecords(getRecord(buffer, bufferRecPos), bigFileBlockRec, field) > 0){
                    continue;//...
            }


            tempBufferRec = getRecord(buffer, bufferRecPos);
            tempBufferBlock = bufferRecPos.block;
            countSameBufferEntries=0;

            while(compareRecords(getRecord(buffer, bufferRecPos), bigFileBlockRec, field)==0){
                //Here we add in output the merges.
                (*outputBlock).entries[(*outputBlock).nreserved++] = bigFileBlockRec;
                (*outputBlock).entries[(*outputBlock).nreserved++] = getRecord(buffer, bufferRecPos);
                (*nres)++;
                if ((*outputBlock).nreserved == MAX_RECORDS_PER_BLOCK) {
                    (*nios) += writeBlock(out, outputBlock);
                    emptyBlock(outputBlock);
                    (*outputBlock).blockid += 1;
                }

                countSameBufferEntries++;
                incr(bufferRecPos);

                if(bufferRecPos.record==0){
                    if(bufferRecPos.block%memSize==firstBlockId%memSize){
                        if (lastBlockId < infile1Size - 1) {
                            (*nios) += readBlock(buffer + firstBlockId%memSize, input1, lastBlockId + 1);
                            firstBlockId++;
                            lastBlockId++;
                        }else {//take always the same value because it is the last value to compare with last big file's blocks
                            if (bufferRecPos.block == 0) {
                                bufferRecPos.block = memSize - 1;
                            } else {
                                bufferRecPos.block -= 1;
                            }
                            bufferRecPos.record = MAX_RECORDS_PER_BLOCK - 1;
                            break;
                        }
                    }
                }
                ////printf("fsdfds");
            }


        }
        //records in bigFileBlock are over and we read the next one.
        bigFileBlockOffset++;
        blocks--;
        (*nios) += readBlock(bigFileBlock, input2, bigFileBlockOffset);
    }








}
/*
 * infile: input filename
 * size: size in blocks of input file
 * outfile: output filename
 * field: which field will be used for sorting
 * buffer: the buffer that is used
 * memSize: number of buffer blocks available for use, without counting the last one, which is for output
 * nunique: number of unique values
 * nios: number of ios
 * 
 * when the input file fits the buffer and there's still a block available for output,
 * hashes each record and writes it to the output, if a record of same value is not
 * found on the corresponding bucket.
 */
void hashElimination(char *infile, uint size, char *outfile, unsigned char field, block_t *buffer, uint memSize, uint *nunique, uint *nios) {
    int out = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
    block_t *bufferOut = buffer + memSize;
    emptyBlock(bufferOut);
    (*bufferOut).valid = true;
    (*bufferOut).blockid = 0;

    (*nunique) = 0;
    (*nios) += readBlocks(infile, buffer, size);

    // creates a hash index. for each value returned from the hash function,
    // there is a linkedList of pointers to the records with that specific hash
    // value
    uint hashSize = size*MAX_RECORDS_PER_BLOCK;
    linkedRecordPtr **hashIndex = (linkedRecordPtr**) malloc(hashSize * sizeof (linkedRecordPtr*));
    for (uint i = 0; i < hashSize; i++) {
        hashIndex[i] = NULL;
    }

    recordPtr start = newPtr(0);
    recordPtr end = newPtr(size * MAX_RECORDS_PER_BLOCK - 1);

    for (; start <= end; incr(start)) {
        if (!buffer[start.block].valid) {
            start.record = MAX_RECORDS_PER_BLOCK - 1;
            continue;
        }
        record_t record = getRecord(buffer, start);
        if (record.valid) {
            // hashes the record being examined
            uint index = hashRecord(infile, record, hashSize, field);
            linkedRecordPtr *element = hashIndex[index];
            // goes through the linked list for the hash value of the record
            // if a record with same value is not found, then a recordPtr is
            // added to the linked list and the record itself is written to
            // the output. otherwise, it is ignored.
            while (element) {
                if (compareRecords(record, getRecord(buffer, element->ptr), field) == 0) {
                    break;
                }
                element = element->next;
            }
            if (!element) {
                element = (linkedRecordPtr*) malloc(sizeof (linkedRecordPtr));
                element->ptr = start;
                element->next = hashIndex[index];
                hashIndex[index] = element;
                (*bufferOut).entries[(*bufferOut).nreserved++] = record;
                (*nunique) += 1;
                if ((*bufferOut).nreserved == MAX_RECORDS_PER_BLOCK) {
                    (*nios) += writeBlocks(out, bufferOut, 1);
                    emptyBlock(bufferOut);
                    (*bufferOut).blockid += 1;
                }
            }
        }
    }
    // writes records left in buffer to the outfile
    if ((*bufferOut).nreserved != 0) {
        (*nios) += writeBlocks(out, bufferOut, 1);
    }
    destroyHashIndex(hashIndex, size);
    close(out);
}
Exemple #16
0
/*
  This file copies the necessary contents of a file to the corresponding location specified by the second arguemnt on the disk.
  The file is first copied to the memory copy of the disk. This is then committed to the actual disk file.
  NOTE: 1. EOF is set only after reading beyond the end of the file. This is the reason why the if condition is needed is needed.
	2. Also the function must read till EOF or BLOCK_SIZE line so that successive read proceeds accordingly
*/
int writeFileToDisk(FILE *f, int blockNum, int type)
{
	int i, line=0,j;
	char buffer[32],s[16],temp[100],c;
	emptyBlock(TEMP_BLOCK);
	if(type==0)			//writing files with assembly code
	{
		char *instr, *arg1, *arg2, *string_start;
		int line_count=0,flag=0,k=0;
		for(i = 0; i < (BLOCK_SIZE/2); i++)
		{
			fgets(temp,100,f);

			string_start=strchr(temp,'"');
			if(string_start==NULL)
			{
				for(k=0;k<31;k++)
					buffer[k]=temp[k];
				buffer[k]='\0';
			}
			else
			{
				if(strlen(string_start)<=16)
				{
					for(k=0;k<31;k++)
						buffer[k]=temp[k];
					buffer[k]='\0';
				}
				else
				{
					for(k=0;k<(strlen(temp)-strlen(string_start)+15);k++)
					{
						buffer[k]=temp[k];
					}
					buffer[k-1]='"';
					buffer[k]='\0';
				}
			}


			if(strlen(buffer)>3)
			{
				if(buffer[strlen(buffer)-1]=='\n')
					buffer[strlen(buffer)-1]='\0';
				instr=strtok(buffer," ");
				arg1=strtok(NULL," ");
				arg2=strtok(NULL,",");

				bzero(s,16);
				if(arg1!=NULL)
				{
					sprintf(s,"%s %s",instr,arg1);
					for(j=strlen(s);j<16;j++)
						s[j]='\0';
					strcpy(disk[TEMP_BLOCK].word[line_count],s);
					if(arg2!=NULL)
					{
						strcpy(s,arg2);
						for(j=strlen(s);j<16;j++)
							s[j]='\0';
						strcpy(disk[TEMP_BLOCK].word[line_count+1],s);

					}
					else
					{
						for(j=0;j<16;j++)
							s[j]='\0';
						strcpy(disk[TEMP_BLOCK].word[line_count+1],s);
					}
					line_count=line_count+2;
				}
				else
				{
					sprintf(s,"%s",instr);
					for(j=strlen(s);j<=16;j++)
						strcat(s,"\0");
					strcpy(disk[TEMP_BLOCK].word[line_count],s);
					bzero(s,16);
					for(j=0;j<16;j++)
						s[j]='\0';
					strcpy(disk[TEMP_BLOCK].word[line_count+1],s);
					line_count=line_count+2;

				}

			}

			 if(feof(f)){
				strcpy(disk[TEMP_BLOCK].word[line_count], "");
				writeToDisk(TEMP_BLOCK,blockNum);
				return -1;
			 }

		}
		writeToDisk(TEMP_BLOCK,blockNum);
		return 1;
	}
	else if(type==1)			//writing data files
	{
		char buffer1[16],c;
		for(i = 0; i < BLOCK_SIZE; i++)
		{
			fgets(buffer1,16,f);
			strcpy(disk[TEMP_BLOCK].word[i],buffer1);
			if(feof(f))
			{
				strcpy(disk[TEMP_BLOCK].word[i], "");
				writeToDisk(TEMP_BLOCK,blockNum);
				return -1;
			}
		}
		writeToDisk(TEMP_BLOCK,blockNum);
		return 1;
	}

}
Exemple #17
0
std::pair<Move, int> AIShell::IDSearchRecurse(int depth, int** state, int turn, int alpha, int beta, struct timeval& start)
{
    std::pair<Move, int> inValid = std::make_pair(Move(-1, -1), -1);
    
    //AI_PIECE bigger better (MAX); HU_PIECE smaller better (MIN).
    int thisAlpha = alpha;
    int thisBeta = beta;
    
    // Create a copy of the current gameState
    int** tempGameState = new int*[numCols];
    for (int col = 0; col < numCols; col++)
    {
        tempGameState[col] = new int[numRows];
        for(int row = 0; row < numRows; row++)
        {
            tempGameState[col][row] = state[col][row];
        }
    }
    
    // Makes sure time is still under the limit
    if(!isUnderLimit(start)) {return inValid;}
    
    // Base Case for MinMax
    if (depth == 0)  //At leaf node, actual move is not important since we just care the eval of this node
    {
        Move dummyMove;
        int hValue = heuristicEval(state, turn, start);
        
        std::pair<Move, int> dummyMoveEval = std::make_pair(dummyMove, hValue);
        return dummyMoveEval;
    }
    
    // Recursive Step for MinMax
    else
    {
        // Search for threats (k-1 in a row) on the board
        std::vector<int> evalNodes;
        std::vector<std::pair<int, int> > movesList = threats(tempGameState);
        
        // If there are no threats find all available moves
        if(movesList.size() == 0 && isUnderLimit(start))
        {
            movesList = emptyBlock(tempGameState);
        }
      
        // Makes sure time is still under the limit
        if(!isUnderLimit(start)) {return inValid;}
        
        for (int i = 0; i < movesList.size(); i++)
        {
            // If there's only 1 possible move.
            if(movesList.size() == 1)
            {
                Move bestMove(movesList[i].first, movesList[i].second);
                std::pair<Move, int> evalValue = std::make_pair(bestMove, 0);
                return evalValue;
            }
            
            // If there's more than 1 possible move.
            tempGameState[movesList[i].first][movesList[i].second] = turn;
            
            if (turn == AI_PIECE){
                int nextLevelEval = IDSearchRecurse(depth - 1, tempGameState, HUMAN_PIECE, thisAlpha, thisBeta, start).second;
                // Makes sure time is still under the limit
                if(!isUnderLimit(start)) {return inValid;}
                
                evalNodes.push_back(nextLevelEval);
                if (nextLevelEval >= thisBeta){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    break;
                }
                
                if (nextLevelEval >= thisAlpha){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    thisAlpha=nextLevelEval;
                }
                
                // Makes sure time is still under the limit
                if(!isUnderLimit(start)) {return inValid;}
                
            }
            
            else{
                int nextLevelEval = IDSearchRecurse(depth - 1, tempGameState, AI_PIECE, thisAlpha, thisBeta, start).second;
                // Makes sure time is still under the limit
                    if(!isUnderLimit(start)) {return inValid;}
                
                evalNodes.push_back(nextLevelEval);
                if (nextLevelEval <= thisAlpha){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    break;
                }
                
                if (nextLevelEval <= thisBeta){
                    sort(movesList, i);
                    evalNodes[0] = nextLevelEval;
                    thisBeta = nextLevelEval;
                }
                // Makes sure time is still under the limit
                if(!isUnderLimit(start)) {return inValid;}
            }
            
            tempGameState[movesList[i].first][movesList[i].second] = 0;   //Set the block back
            // Makes sure time is still under the limit
            if(!isUnderLimit(start)) {return inValid;}
        }
        
        if (turn == AI_PIECE)
        {
                
            Move bestMove(movesList[0].first, movesList[0].second);
            std::pair<Move, int> evalValue = std::make_pair(bestMove, evalNodes[0]);
                
            deleteBoard(tempGameState);
                
            // Makes sure time is still under the limit
            if(!isUnderLimit(start)) {return inValid;}
                
            return evalValue;
        }
            
        else
        {
            Move bestMove(movesList[0].first, movesList[0].second);
            std::pair<Move, int> evalValue = std::make_pair(bestMove, evalNodes[0]);
                
            deleteBoard(tempGameState);
                
            // Makes sure time is still under the limit
            if(!isUnderLimit(start)) {return inValid;}
                
            return evalValue;
        }
    }
}
/*
 * infile: filename of the input file
 * outfile: filename of the output file
 * field: which field will be used for sorting
 * buffer: the buffer used
 * nmem_blocks: size of buffer
 * nunique: number of unique values
 * nios: number of ios
 * 
 * when the input file size is equal to buffer, the whole file is loaded and
 * sorted. then the first block is used as output where only unique values are
 * written
 */
void useFirstBlock(char *infile, char *outfile, unsigned char field, block_t *buffer, uint nmem_blocks, uint *nunique, uint *nios) {
    int out = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
    (*nios) += readBlocks(infile, buffer, nmem_blocks);
    if (sortBuffer(buffer, nmem_blocks, field)) {
        // all the unique values of the first block are shifted to the start
        // of it. the rest are marked as invalid
        recordPtr i = newPtr(1);
        recordPtr j = newPtr(1);
        (*nunique) += 1;
        buffer[0].nreserved = 1;
        for (; j.block < 1; incr(j)) {
            record_t record = getRecord(buffer, j);
            if (record.valid && compareRecords(record, getRecord(buffer, i - 1), field) != 0) {
                setRecord(buffer, record, i);
                (*nunique) += 1;
                incr(i);
                buffer[0].nreserved += 1;
            }
        }

        j = newPtr(i, 0);
        for (; j.block < 1; incr(j)) {
            buffer[j.block].entries[j.record].valid = false;
        }

        record_t *lastRecordAdded = (record_t*) malloc(sizeof (record_t));
        record_t lastUnique = getRecord(buffer, i - 1);
        memcpy(lastRecordAdded, &lastUnique, sizeof (record_t));
        // if the first block is full after the shifting (meaning that all its
        // values were actually unique), writes it to the outfile and empties it
        if (buffer[0].nreserved == MAX_RECORDS_PER_BLOCK) {
            i.block -= 1;
            (*nios) += writeBlocks(out, buffer, 1);
            emptyBlock(buffer);
            buffer[0].blockid += 1;
        }

        // write the unique values of the other blocks to the first one. if it
        // becomes full writes it to outfile and empties it. at the end, if it
        // has records not writtend yet, writes them to the outfile as well.
        j = newPtr(MAX_RECORDS_PER_BLOCK);
        while (buffer[j.block].valid && j.block < nmem_blocks) {
            record_t record = getRecord(buffer, j);
            if (!record.valid) {
                break;
            }
            if (compareRecords(record, (*lastRecordAdded), field) != 0) {
                setRecord(buffer, record, i);
                memcpy(lastRecordAdded, &record, sizeof (record_t));
                (*nunique) += 1;
                incr(i);
                buffer[0].nreserved += 1;
            }
            if (buffer[0].nreserved == MAX_RECORDS_PER_BLOCK) {
                i.block -= 1;
                (*nios) += writeBlocks(out, buffer, 1);
                emptyBlock(buffer);
                buffer[0].blockid += 1;
            }
            incr(j);
        }
        if (buffer[0].nreserved != 0) {
            (*nios) += writeBlocks(out, buffer, 1);
        }
        free(lastRecordAdded);
    }
    close(out);
}