· 8 years ago · Mar 27, 2018, 04:22 AM
1#include <stdlib.h>
2#include <stdio.h>
3#include <string.h>
4#include <math.h>
5
6/* constants */
7#define BUFFER_SIZE 1024
8#define FILENAME_SIZE 20
9#define blockCount 20
10#define columnCount 5
11#define MOD_AMT 5
12
13/* decoding CSV data */
14typedef struct CSVLinkedList {
15 char *operation;
16 int data;
17 struct CSVLinkedList *next;
18}CSVData;
19
20/* to store directory information */
21typedef struct Node {
22 int indexKey;
23 int startBlock;
24 int endBlock;
25} Node_index;
26
27typedef struct FreeSpace {
28 int blockNum;
29 struct FreeSpace *next;
30}freeSpace;
31
32// function prototypes
33void processCSV(CSVData *data);
34void clearCache();
35void readAtIndex(int indexRead);
36void initialise();
37
38/* MEMORY STRUCTURE */
39int memoryStructure[blockCount][columnCount];
40Node_index *directoryStructure[5];
41
42// counting number of entries in the memoryStructure
43int fileCount = 0;
44int allocationType = 0, i, j;
45
46/* for free space management (pointing to all free blocks) */
47freeSpace *freeSpaceHead;
48
49int main() {
50 initialise();
51
52 // giving user choice of memory allocation type
53 while (1) {
54 printf("Welcome to ICT1007 Assignment\n");
55 printf("Please choose the memory allocation type.\n1. Contiguous\n2. Linked\n3. Indexed\nEnter your choice: ");
56 scanf_s("%d", &allocationType);
57 clearCache();
58 if (allocationType == 1) {
59 printf("You have selected <Contiguous> memory allocation.\n\n");
60 }
61 else if (allocationType == 2) {
62 printf("You have selected <Linked> memory allocation.\n\n");
63 //remainingSpace = blockCount * (columnCount - 1);
64 }
65 else if (allocationType == 3) {
66 printf("You have selected <Indexed> memory allocation.\n\n");
67 }
68 else
69 printf("You have selected an invalid option. Please try again.\n");
70
71 // print main menu
72 int userChoice = -1;
73 while (userChoice != 5) {
74 printf("Main Menu\n");
75 printf("1. Import CSV file\n2. View directory structure\n3. View data structure\n4. Use another memory allocation algorithm\n5. Exit\nEnter your choice: ");
76 scanf_s("%d", &userChoice);
77
78 /* to clear input buffer from scanf */
79 clearCache();
80
81 if (userChoice == 1) {
82 /* to read the CSV file*/
83 char fileName[FILENAME_SIZE];
84 printf("Enter name of CSV file to import into system: ");
85 fgets(fileName, FILENAME_SIZE, stdin);
86
87 //to remove trailing \n
88 fileName[strcspn(fileName, "\n")] = 0;
89 FILE *file;
90
91 char buf[BUFFER_SIZE];
92 int validFile = 1;
93 file = fopen(fileName, "r");
94 if (file == NULL) {
95 fprintf(stderr, "File not found.\n");
96 validFile = 0;
97 }
98 if (validFile == 1) {
99 // To check number of records in the file
100 CSVData *newEntry;
101 // to read buf
102 while (fgets(buf, sizeof(buf), file) != NULL) {
103 newEntry = malloc(sizeof(CSVData));
104 newEntry->next = NULL;
105 newEntry->data = NULL;
106
107 // this strtok will return the operation type of the line
108 char *operationType = strtok(buf, ",");
109 // recording file details
110 newEntry->operation = operationType;
111
112 // this strtok will return the file identifier
113 char *tokenPtr = "";
114 while (tokenPtr != NULL)
115 {
116 tokenPtr = strtok(NULL, ",");
117 if (newEntry->data == NULL) {
118 // recording file details
119 newEntry->data = tokenPtr;
120 }
121 else {
122 if (tokenPtr != NULL) {
123 // checking if there is a newline character in the token
124 if (strchr(tokenPtr, '\n') != NULL) {
125 //to remove trailing \n
126 tokenPtr[strcspn(tokenPtr, "\n")] = 0;
127 if (strcmp(tokenPtr, "") == 0) {
128 processCSV(newEntry);
129 break;
130 }
131 }
132
133 CSVData *subsequentEntry = malloc(sizeof(CSVData));
134 subsequentEntry->next = NULL;
135 subsequentEntry->operation = operationType;
136 subsequentEntry->data = tokenPtr;
137 // iterate through head of the node to find the next node to append the newly created node to
138 CSVData *temp = newEntry;
139 while (temp->next != NULL) {
140 temp = temp->next;
141 }
142 temp->next = subsequentEntry;
143 }
144 }
145 }
146 if (tokenPtr == NULL) {
147 processCSV(newEntry);
148 }
149 }
150 if (feof(file))
151 {
152 // print completed message
153 printf("CSV File loaded.\n\n");
154 }
155 else
156 {
157 // some other error interrupted the read
158 fprintf(stderr, "Error reading file\n");
159 }
160 }
161 }
162 else if (userChoice == 2) {
163 /*PRINTING OF NODE LINKED LIST*/
164 printf("\nPRINTING INFORMATION OF NODES\n");
165 for (i = 0; i < MOD_AMT; i++) {
166 printf("Node %d: ", i);
167 if (directoryStructure[i] != NULL)
168 printf("FileID: %d, Start block: %d, End block: %d", directoryStructure[i]->indexKey, directoryStructure[i]->startBlock, directoryStructure[i]->endBlock);
169 else
170 printf("No information found.");
171
172 printf("\n");
173 }
174 printf("\n");
175 }
176 else if (userChoice == 3) {
177 // view entire memory structure
178
179 printf("\nPRINTING ENTIRE MEMORY STRUCTURE");
180
181 // printing directory structure
182 printf("\nBlock Number: 0\n");
183 for (i = 0; i < MOD_AMT; i++) {
184 printf("Index Number %d: ", i);
185 if (directoryStructure[i] != NULL)
186 printf("FileID - %d, Starting block - %d, Ending block - %d\n", directoryStructure[i]->indexKey, directoryStructure[i]->startBlock, directoryStructure[i]->endBlock);
187 else
188 printf("No information found.\n");
189 }
190
191 // printing memory structure
192 for (i = 1; i < blockCount; i++) {
193 printf("\nBlock Number: %d\n", i);
194 for (j = 0; j < columnCount; j++) {
195 if (allocationType == 2) {
196 printf("Index Number %d: %d\n", j, memoryStructure[i][j]);
197 }
198 else
199 printf("Index Number %d: %d\n", j, memoryStructure[i][j]);
200 }
201 }
202
203 // printing record information
204 printf("Total number of files: %d\n\n", fileCount);
205 printf("Total records: %d\n\n", getRecordCount());
206 }
207 else if (userChoice == 4) {
208 // re init the memory structure
209 initialise();
210 break;
211 }
212 else if (userChoice == 5) {
213 printf("Thank you for using the system.\nPress any key to continue.");
214 getch();
215 return 0;
216 }
217 else {
218 printf("Invalid choice selected, please try again.\n\n");
219 }
220 }
221 }
222}
223
224/* this method will update the block in use - return 1 if success, 0 if fail */
225int updateBlockInUse(int blockNum) {
226 freeSpace *temp = freeSpaceHead;
227 freeSpace *prev = NULL;
228 /* iterate through all the data to find the block to delete */
229 while (temp != NULL) {
230 if (blockNum == temp->blockNum) {
231 /* delete block from linked list */
232 // if delete at head
233 if (temp->blockNum == freeSpaceHead->blockNum){
234 prev = freeSpaceHead;
235 freeSpaceHead = freeSpaceHead->next;
236 }
237 else {
238 prev->next = temp->next;
239 }
240
241 return 1;
242 }
243 prev = temp;
244 temp = temp->next;
245 }
246 /* did not find the block number, return 0 */
247 return 0;
248}
249
250/* this method will removes the block in use (adds the blocks back into the free space linked list's head */
251void removeBlockInUse(int blockNum, int toSkip) {
252 freeSpace *temp = freeSpaceHead;
253 freeSpace *prev = NULL;
254 /* to insert at right location */
255 for (i = 0; i < toSkip; i++) {
256 prev = temp;
257 temp = temp->next;
258 }
259 /* insert at head */
260 if (prev == NULL) {
261 /* creation of new entry */
262 freeSpace *newFreeSpace = (freeSpace *)malloc(sizeof(freeSpace));
263 newFreeSpace->blockNum = blockNum;
264 newFreeSpace->next = temp;
265 freeSpaceHead = newFreeSpace;
266 }
267 /* not insert at head */
268 else {
269 /* creation of new entry */
270 freeSpace *newFreeSpace = (freeSpace *)malloc(sizeof(freeSpace));
271 newFreeSpace->blockNum = blockNum;
272 prev->next = newFreeSpace;
273 newFreeSpace->next = temp;
274 }
275}
276
277/* this method will check if there is enough space for the file information to be stored */
278freeSpace *checkSpace(int requiredBlocks) {
279 freeSpace *temp = freeSpaceHead;
280 freeSpace *toReturn = freeSpaceHead;
281
282 /* contiguous - have to check if there are enough continuous blocks to be used */
283 if (allocationType == 1) {
284 int contBlocks = 0;
285 while (temp != NULL) {
286 /* checking if the blocks are continuous */
287
288 if (contBlocks == requiredBlocks)
289 /* return if there is enough space */
290 return toReturn;
291
292 int prevBlock = temp->blockNum;
293 /* next block is NULL, this means unable to allocate enough blocks */
294 if (temp == NULL)
295 return NULL;
296 else {
297 int nextBlock = temp->next->blockNum;
298 if (nextBlock == prevBlock + 1) {
299 /* they are continuous blocks, increment counter */
300 contBlocks++;
301 temp = temp->next;
302 }
303 else {
304 /* they are not continuous blocks, reset counter to 0 */
305 contBlocks = 0;
306 toReturn = temp->next;
307 }
308 }
309 }
310 /* if temp becomes NULL, this means there is not enough space */
311 return NULL;
312
313 }
314 /* linked and indexed - have to check if there are enough blocks to be used */
315 else {
316 int allocateBlock = temp->blockNum;
317 /* iterate through linked list to count number of nodes left to determine if there is enough space */
318 for (i = 0; i < requiredBlocks; i++) {
319 /* if temp becomes NULL, this means there is not enough space */
320 if (temp == NULL)
321 return NULL;
322 temp = temp->next;
323 }
324 /* program will run till here if there is enough space, return freeSpaceHead for program to allocate file information to this block */
325 return freeSpaceHead;
326 }
327}
328
329// this function returns the end block number after successfully committing all information into the memory structure
330int updateMemory(CSVData *currentNode, freeSpace *allocated) {
331 /* for contigous memory allocation type */
332 int blockNum = allocated->blockNum;
333 if (allocationType == 1) {
334 int counter = 0;
335 while (currentNode != NULL) {
336 if (counter != 5) {
337 // getting the file data
338 int fileInfo;
339 sscanf(currentNode->data, "%d", &fileInfo);
340
341 // update the memory structure
342 memoryStructure[blockNum][counter] = fileInfo;
343
344 // to update the counter so the system will update next index of the block
345 counter++;
346 currentNode = currentNode->next;
347 }
348 else {
349 // reset counter and increment blockNum
350 allocated = allocated->next;
351 int newBlockNum = allocated->blockNum;
352 /* update the new block that is in use */
353 int success = updateBlockInUse(newBlockNum);
354 if (success == 1) {
355 // ptr to next block
356 printf(", %d", newBlockNum);
357 memoryStructure[blockNum][counter] = newBlockNum;
358 counter = 0;
359 blockNum = newBlockNum;
360 }
361 }
362 }
363 return blockNum;
364 }
365 /* for linked disk block allocation method */
366 if (allocationType == 2) {
367 int counter = 0;
368 while (currentNode != NULL) {
369 if (counter != 4) {
370 // getting the file data
371 int fileInfo;
372 sscanf(currentNode->data, "%d", &fileInfo);
373
374 // update the memory structure
375 memoryStructure[blockNum][counter] = fileInfo;
376
377 // to update the counter so the system will update next index of the block
378 counter++;
379 currentNode = currentNode->next;
380 }
381 else {
382 // reset counter and increment blockNum
383 allocated = allocated->next;
384 int newBlockNum = allocated->blockNum;
385 /* update the new block that is in use */
386 int success = updateBlockInUse(newBlockNum);
387 if (success == 1) {
388 // ptr to next block
389 printf(", %d", newBlockNum);
390 memoryStructure[blockNum][counter] = newBlockNum;
391 counter = 0;
392 blockNum = newBlockNum;
393 }
394 }
395 }
396 return blockNum;
397 }
398
399 else if (allocationType == 3) {
400 int endBlock = blockNum;
401 // for indexed memory allocation method:
402 // first block is burned to contain the pointers to all the blocks occupied by a file
403
404 // initialise all indexes to -1 when block is found
405 for (int x = 0; x < 5; x++) {
406 memoryStructure[endBlock][x] = -1;
407 }
408 // find new block to store file information
409 allocated = allocated->next;
410 int newBlock = allocated->blockNum;
411 /* update the new block that is in use */
412 int success = updateBlockInUse(newBlock);
413 if (success == 1) {
414 printf(", %d", newBlock);
415 // assign the block number to the index table
416 int j = 0;
417 memoryStructure[endBlock][j] = newBlock;
418 //memoryStructure[blockNum][4] = -1;
419
420 CSVData *temp = currentNode;
421 int count = 0;
422 while (temp != NULL) {
423 // find new block to store file information when space of block has been used up
424 if (count > 4) {
425 /* for new block to store file information */
426 allocated = allocated->next;
427 newBlock = allocated->blockNum;
428 int success = updateBlockInUse(newBlock);
429 if (success == 1) {
430 printf(", %d", newBlock);
431 count = 0;
432 j++;
433 // the last index of the block is linked to another block to store new block pointer
434 if (j == 4) {
435 // find new block to when space has been used up for index table
436 int temp = endBlock;
437 endBlock = allocated->blockNum;
438 memoryStructure[temp][j] = endBlock;
439 for (int y = 0; y < 5; y++) {
440 memoryStructure[endBlock][y] = -1;
441 }
442 allocated = allocated->next;
443 newBlock = allocated->blockNum;
444 int success = updateBlockInUse(newBlock);
445 if (success == 1) {
446 printf(", %d", newBlock);
447 memoryStructure[endBlock][count] = newBlock;
448 j = 0;
449 }
450 }
451 else {
452 memoryStructure[endBlock][j] = newBlock;
453 }
454 }
455 }
456 // append file info into block index
457 if (memoryStructure[newBlock][count] == 0) {
458 int fileInfo;
459 sscanf(temp->data, "%d", &fileInfo);
460 memoryStructure[newBlock][count] = fileInfo;
461 }
462 temp = temp->next;
463 count++;
464 }
465 return endBlock;
466
467 }
468 }
469}
470
471/* returns which index the new data will reside in directoryStructure (0 to 4), returns -1 if unable to add */
472int insertAtIndex(int indexKey, int startBlock) {
473 //int currentFreeIndex = findEmptySpace(memoryStructure);
474 /* MALLOC new node only if there are less than 5 files created */
475 if (fileCount > 4) {
476 return -1;
477 }
478 else {
479 Node_index *mallocNode = (Node_index *)malloc(sizeof(Node_index));
480
481 Node_index *tempHead = NULL;
482 int hashValue = (indexKey / 100) % MOD_AMT;
483
484 if (directoryStructure[hashValue] == NULL) {
485 // able to insert the new file into the directoryStructure in index hashValue
486 mallocNode->indexKey = indexKey;
487 mallocNode->startBlock = startBlock;
488
489 directoryStructure[hashValue] = mallocNode;
490
491 return hashValue;
492 }
493 else {
494 // linear probing - TO DO maybe change to quadratic probing?
495 for (i = 0; i < MOD_AMT - 1; i++) {
496 // try only MOD_AMT - 1 more times
497 hashValue += 1;
498 if (hashValue > 4)
499 hashValue = 0;
500 if (directoryStructure[hashValue] == NULL) {
501 // found an empty entry
502
503 // able to insert the new file into the directoryStructure in index hashValue
504 mallocNode->indexKey = indexKey;
505 mallocNode->startBlock = startBlock;
506
507 directoryStructure[hashValue] = mallocNode;
508
509 return hashValue;
510 }
511 }
512 }
513 }
514}
515
516void updateEndBlock(int indexKey, int endBlock) {
517 for (i = 0; i < MOD_AMT; i++) {
518 if (directoryStructure[i] != NULL) {
519 if (directoryStructure[i]->indexKey == indexKey) {
520 directoryStructure[i]->endBlock = endBlock;
521 break;
522 }
523 }
524 }
525}
526
527/**
528DELETES HASHMAP AT INDEX, REMOVES FROM MEMORY BLOCK TOO
529- parameter indexKey: To delete the index of the file, e.g. 100, 200, 300.
530*/
531void deleteAtIndex(int indexKey) {
532 /* checking if the indexKey exists */
533 int ifExists = getDirIndex(indexKey);
534 if (ifExists != -1) {
535 // print out the blocks that are deleted
536 printf("Deleting File ID %d at block(s) %d", indexKey, directoryStructure[ifExists]->startBlock);
537
538 // to delete the entries from memory structure
539 int xCoordinate = directoryStructure[ifExists]->startBlock;
540 int yCoordinate = 0;
541
542 // adding back the blocks back into the linked free space list
543 int delCount = 0;
544 removeBlockInUse(xCoordinate, delCount);
545
546 /* for contiguous memory allocation type */
547 if (allocationType == 1) {
548 // delete all blocks from xCoordinate to endBlock
549 int endBlock = directoryStructure[ifExists]->endBlock;
550
551 while (yCoordinate <= 5) {
552 // changing the xCoordinate to the pointer if the compiler has reached the index of the pointer
553 if (yCoordinate == 5) {
554 // to set xCoordinate to next block
555 xCoordinate++;
556 if (xCoordinate > endBlock)
557 break;
558 else {
559 // print out the blocks that are deleted
560 printf(", %d", xCoordinate);
561 // reset yCooridinate back to 0 to delete the information from the first index of the next block
562 yCoordinate = 0;
563
564 // add the block back into the linked free space list
565 delCount++;
566 removeBlockInUse(xCoordinate, delCount);
567 }
568 }
569 else {
570 // delete whole block worth of data
571 memoryStructure[xCoordinate][yCoordinate] = 0;
572 yCoordinate += 1;
573 }
574 }
575 }
576 /* for linked file allocation type */
577 else if (allocationType == 2) {
578 while (yCoordinate != 5) {
579 // changing the xCoordinate to the pointer if the compiler has reached the index of the pointer
580 if (yCoordinate == 4 && memoryStructure[xCoordinate][yCoordinate] != 0) {
581 int updatedXCoordinate = memoryStructure[xCoordinate][yCoordinate];
582 memoryStructure[xCoordinate][yCoordinate] = 0;
583 yCoordinate = 0;
584 xCoordinate = updatedXCoordinate;
585 // print out the blocks that are deleted
586 printf(", %d", xCoordinate);
587
588 // add the block back into the linked free space list
589 delCount++;
590 removeBlockInUse(xCoordinate, delCount);
591 }
592 else {
593 // delete whole block worth of data
594 memoryStructure[xCoordinate][yCoordinate] = 0;
595 yCoordinate += 1;
596 }
597 }
598 }
599
600 else if (allocationType == 3) {
601 int ifExists = getDirIndex(indexKey);
602 int newBlockPonter;
603 int blockPointer;
604
605 // delete from memory structure
606 int block = directoryStructure[ifExists]->startBlock;
607 for (int i = 0; i < columnCount; i++) {
608 if (memoryStructure[block][i] != -1) {
609 // when reach the last index of block pointer, go to another block pointer
610 if (i == 4) {
611 int temp = block;
612 // block pointer here - index 4 pointing to another block pointer
613 block = memoryStructure[block][i];
614 printf(", %d", block);
615
616 // add the block back into the linked free space list
617 delCount++;
618 removeBlockInUse(block, delCount);
619
620 // delete last block index of block pointer
621 memoryStructure[temp][i] = 0;
622 // reset count to 0
623 i = 0;
624 }
625 int fileBlock = memoryStructure[block][i];
626 printf(", %d", fileBlock);
627 // add the block back into the linked free space list
628 delCount++;
629 removeBlockInUse(fileBlock, delCount);
630 // file block index set to 0
631 for (int j = 0; j < columnCount; j++) {
632 memoryStructure[fileBlock][j] = 0;
633 }
634 // delete information from indexing block
635 memoryStructure[block][i] = 0;
636 }
637 else {
638 // replace remaining indexes with -1 value fromthe indexing block with a value of 0
639 for (int i = 0; i < columnCount; i++) {
640 memoryStructure[block][i] = 0;
641 }
642 break;
643 }
644 }
645 }
646
647 // delete from directory structure
648 directoryStructure[ifExists] = NULL;
649 // print delete information
650 printf(".\nSuccessfully deleted file ID %d.\n\n", indexKey);
651 fileCount--;
652 }
653 else {
654 printf("File ID %d does not exist!\n\n", indexKey);
655 }
656}
657
658/* returns index of the indexKey searched in directory structure. If found return 1, else, return -1 */
659int getDirIndex(int indexKey) {
660 for (i = 0; i < MOD_AMT; i++) {
661 if (directoryStructure[i] != NULL) {
662 if (directoryStructure[i]->indexKey == indexKey) {
663 return i;
664 }
665 }
666 }
667 return -1;
668}
669
670/* this method will check if a specified index exists in the memory structure. Returns the block number, 0 if does not exist. */
671int valueExists(int indexKey) {
672 // check if the searched index exists
673 for (int i = 0; i < blockCount; i++) {
674 for (int j = 0; j < columnCount; j++) {
675 if (memoryStructure[i][j] == indexKey)
676 return i;
677 }
678 }
679 return -1;
680}
681
682/* this method gets rid of old values from scanf after the user input checks that the user has entered invalid values */
683void clearCache() {
684 char a;
685 while ((a = getchar()) != '\n' && a != EOF);
686}
687
688void readAtIndex(int indexRead) {
689 /* for contiguous memory allocation */
690 if (allocationType == 1) {
691 // getting the file ID of the specified index
692 int fileID = floor(indexRead / 100) * 100;
693
694 // finding out which hashmap the file is stored in
695 int mod = fileID % MOD_AMT;
696
697 // getting the file ID
698 int ifExists = getDirIndex(fileID);
699 if (ifExists != -1) {
700 int blockPtr = directoryStructure[ifExists]->startBlock;
701 // print results
702 printf("Reading file ID %d containing specified value %d from block %d.\n", fileID, indexRead, blockPtr);
703
704 // stepping through the memory structure
705 for (int i = 0; i < columnCount; i++) {
706 if (memoryStructure[blockPtr][i] == indexRead) {
707 // found
708 printf("Found! Specified value %d is located in block %d index %d.\n\n", indexRead, blockPtr, i);
709 // to break out of for loop
710 i = 4;
711 }
712 else if (i == 4) {
713 printf("Block %d does not contain the specified value %d. ", blockPtr, indexRead);
714 // change the pointer value
715 //blockPtr = memoryStructure[blockPtr][i];
716 if (blockPtr <= blockCount) {
717 blockPtr++;
718 // restart the iteration through memory structure in the new block
719 i = -1;
720 printf("Proceeding to search in block %d.\n", blockPtr);
721 }
722 else {
723 printf("Unable to find this specific value %d: ", indexRead);
724 }
725 }
726 }
727 }
728 }
729
730 /* for linked memory allocation */
731 else if (allocationType == 2) {
732 // getting the file ID of the specified index
733 int fileID = floor(indexRead / 100) * 100;
734
735 // finding out which hashmap the file is stored in
736 int mod = fileID % MOD_AMT;
737
738 // getting the file ID
739 int ifExists = getDirIndex(fileID);
740 if (ifExists != -1) {
741 int blockPtr = directoryStructure[ifExists]->startBlock;
742 // print results
743 printf("Reading file ID %d containing specified value %d from block %d.\n", fileID, indexRead, blockPtr);
744
745 // stepping through the memory structure
746 for (int i = 0; i < columnCount; i++) {
747 if (memoryStructure[blockPtr][i] == indexRead) {
748 // found
749 printf("Found! Specified value %d is located in block %d index %d.\n\n", indexRead, blockPtr, i);
750 // to break out of for loop
751 i = 4;
752 }
753 else if (i == 4) {
754 printf("Block %d does not contain the specified value %d. ", blockPtr, indexRead);
755 // change the pointer value
756 blockPtr = memoryStructure[blockPtr][i];
757 // restart the iteration through memory structure in the new block
758 i = -1;
759 printf("Proceeding to search in block %d.\n", blockPtr);
760 }
761 }
762 }
763 }
764 else if (allocationType == 3) {
765 // getting the filed id
766 int fileId = floor(indexRead / 100) * 100;
767 int modValue = fileId % MOD_AMT;
768 int ifExists = getDirIndex(fileId);
769 if (ifExists != -1) {
770 int block = directoryStructure[ifExists]->startBlock;
771 // print results
772 printf("Reading file ID %d containing specified value %d from block %d.\n", fileId, indexRead, block);
773 //step through the memory structure
774 int blockPointer;
775 int outerLoopBreak = 0;
776 i = 0;
777 while (i < blockCount) {
778 if (memoryStructure[block][i] != -1) {
779 if (i == 4) {
780 // get new block when idexes hit 4
781 block = memoryStructure[block][i];
782 //printf("Reading");
783 i = 0;
784 printf("Block %d does not contain the specified value %d. Proceeding to search in block %d.\n", blockPointer, indexRead, block);
785 }
786 blockPointer = memoryStructure[block][i];
787 if (blockPointer != -1) {
788 for (int j = 0; j < columnCount; j++) {
789 if (memoryStructure[blockPointer][j] == indexRead) {
790 // found
791 printf("Found! Specified value %d is located in block %d index %d.\n\n", indexRead, blockPointer, j);
792 outerLoopBreak = 1;
793 break;
794 }
795 }
796 if (outerLoopBreak == 1)
797 break;
798 printf("Block %d does not contain the specified value %d. Proceeding to search in block %d.\n", blockPointer, indexRead, memoryStructure[block][i + 1]);
799 }
800 }
801 i++;
802 }
803 }
804 }
805}
806
807void processCSV(CSVData *data) {
808 int blockNum = 0;
809 CSVData *temp = data;
810 if (temp != NULL) {
811 /* converting the data into an integer type */
812 int indexKey;
813 // see which operation the file has specified the program to do
814 if (strcmp(temp->operation, "add") == 0) {
815 /* record number of elements to add into memory structure */
816 int additionCount = 0;
817 CSVData *dataCounter = data;
818 while (dataCounter != NULL) {
819 additionCount++;
820 dataCounter = dataCounter->next;
821 }
822 // decrease additionCount by 1 because minus off the directory record
823 additionCount -= 1;
824
825 // contiguous requires 5 index per block
826 if (allocationType == 2)
827 additionCount = ceil(additionCount / 5.0);
828
829 // linked requires 4 indexes per block
830 else if (allocationType == 2)
831 additionCount = ceil(additionCount / 4.0);
832
833 else if (allocationType == 3) {
834 int fileInfoCount = additionCount;
835 /* for counting how many blocks required */
836 int blocks = 0, counter = 0;
837 while (fileInfoCount > 0) {
838 /* require one more block for the indexing of blocks */
839 if (counter == 0) {
840 counter = 4;
841 blocks++;
842 }
843
844 /* storing 5 file information in 1 block */
845 blocks++;
846 fileInfoCount -= 5;
847 counter--;
848 }
849 additionCount = blocks;
850 }
851
852 sscanf(temp->data, "%d", &indexKey);
853 // first, create the entry in the hashmap
854 int startBlock = 0;
855 int endBlock = 0;
856
857 // checking if the file ID already exists in the data structure / hashmap
858 int ifExists = getDirIndex(indexKey);
859 if (ifExists != -1) {
860 printf("Unable to insert data with file ID %d as it already exists.\n\n", indexKey);
861 }
862 else {
863 // finding empty index to insert
864 freeSpace *allocated = checkSpace(additionCount);
865
866 if (allocated == NULL) {
867 printf("You do not have enough memory to insert data with file ID %d.\n\n", indexKey);
868 }
869 else {
870 startBlock = allocated->blockNum;
871 //this will creates the file details at the hashmap
872 int ifInserted = insertAtIndex(indexKey, startBlock);
873
874 // successfully inserted
875 if (ifInserted != -1) {
876 printf("Adding file ID %d at block(s) %d", indexKey, startBlock);
877
878 /* delete the block from the linked free space list */
879 int updatedFreeBlocks = updateBlockInUse(allocated->blockNum);
880
881 // proceeding to adding file information
882 temp = temp->next;
883 int finalEndBlock = startBlock;
884 if (temp != NULL) {
885 // then, iterate through the given data to populate the memory structure
886 finalEndBlock = updateMemory(temp, allocated);
887 }
888 // update the end message of block numbers
889 updateEndBlock(indexKey, finalEndBlock);
890 printf("\nSuccessfully added file ID %d\n\n", indexKey);
891 fileCount++;
892 }
893 else {
894 printf("Adding file ID %d failed.\n", indexKey);
895 printf("Unable to create more than 5 files.\n\n");
896 }
897 }
898 }
899 }
900 else if (strcmp(temp->operation, "read") == 0) {
901 sscanf(temp->data, "%d", &indexKey);
902 // checking if specified index exists.
903 int ifExists;
904 ifExists = valueExists(indexKey);
905 /* printing error if does not exist */
906 if (ifExists == -1) {
907 printf("Error reading file content %d. Records not found.\n\n", indexKey);
908 }
909 /* proceed with reading if exist */
910 else {
911 readAtIndex(indexKey);
912 }
913 }
914 else if (strcmp(temp->operation, "delete") == 0) {
915 sscanf(temp->data, "%d", &indexKey);
916 deleteAtIndex(indexKey);
917 }
918 else {
919 printf("Error! Unknown operation found.\n");
920 }
921
922 // free the memory that allocated.
923 free(data);
924 }
925 else {
926
927 }
928}
929
930int getRecordCount() {
931 int recordCount = 0;
932
933 /* counting directory structure entries */
934 for (i = 0; i < MOD_AMT; i++) {
935 if (directoryStructure[i] != NULL)
936 recordCount++;
937 }
938
939 /* counting memory structure entries */
940 for (i = 1; i < blockCount; i++) {
941 for (int j = 0; j < columnCount; j++) {
942 if (memoryStructure[i][j] != 0) {
943 recordCount++;
944 }
945 }
946 }
947 return recordCount;
948}
949
950void initialise() {
951 /* INITIALIZE MEMORY BLOCK */
952 for (i = blockCount - 1; i >= 0; i--) {
953 // start from blockCount, slowly decrement for the adding of free space to be in ascending order
954 for (j = 0; j < columnCount; j++) {
955 // make first index of the memory structure to be 1 to indicate that it cannot be populated with data
956 if (i == 0)
957 memoryStructure[i][j] = 1;
958 else {
959 memoryStructure[i][j] = 0;
960 // insert at head of the free space pointer when the whole block is free (when j is 4 all indexes of the block are cleared)
961 if (j == 4) {
962 freeSpace *newFreeSpace = (freeSpace *)malloc(sizeof(freeSpace));
963 newFreeSpace->blockNum = i;
964 newFreeSpace->next = freeSpaceHead;
965 freeSpaceHead = newFreeSpace;
966 }
967 }
968 }
969 }
970 for (i = 0; i < MOD_AMT; i++)
971 directoryStructure[i] = NULL;
972
973 fileCount = 0;
974}