-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstorage_mgr.c
287 lines (244 loc) · 9.07 KB
/
storage_mgr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#include "storage_mgr.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "dberror.h"
FILE *file;
//initate Storage Manager
void initStorageManager()
{
printf("Sucessfully Initate Storage Manager\n");
}
//Local function prototype declaration
RC createFile(char *fileName);
RC validateFileHandle (SM_FileHandle *filehandle);
RC validateFile (int pageNum, SM_FileHandle *filehandle);
// create new file of one page
RC createFile(char *fileName) {
RC code;
file = fopen(fileName,"w");
//Allocate memory a single page with page size as 2mb i.e 2048 bytes with calloc function
char *ptr=(char *)calloc(PAGE_SIZE,sizeof(char));
//Write the single page of 2mb size to a file
if(fwrite(ptr,sizeof(char),PAGE_SIZE,file) == PAGE_SIZE) {
//Move the file pointer to the end of the file
fseek(file,0,SEEK_END);
//Free the memory allocated by calloc
free(ptr);
//Close the file
fclose(file);
RC_message="File creation has been completed!!";
code = RC_OK;
}
else {
free(ptr);
RC_message="Page Creation Failed";
code = RC_WRITE_FAILED;
}
return code;
}
RC createPageFile (char *fileName) {
/*Here we are creating a new file,as per the requirement the initial
file size should be one page , and this single page should be filled
with 0 bytes. Hence we need to use calloc() version of dynamic memory
allocation , since by default all the blocks created are intialized to 0
instead of garbage values
*/
RC code;
//Initialize the input variable
char input;
//Open File
file = fopen(fileName,"r");
code = createFile(fileName);
return code;
}
RC openPageFile(char *fileName,SM_FileHandle *fileHandle) {
/*This function opens a page file ans sets the properties of the file handler like
mgmtIngo , page count and current position of the new file. The function also calculates
the number of pages in the file*/
RC code = RC_OK;
//Open a a page file
fileHandle -> mgmtInfo = fopen(fileName,"r+");
int pageCnt,filesize;
if(fileHandle->mgmtInfo==NULL){
RC_message ="File does not exist";
code = RC_FILE_NOT_FOUND;
}
else{
fileHandle -> fileName = fileName;
fileHandle -> curPagePos = ftell(fileHandle ->mgmtInfo)/PAGE_SIZE;
fseek(fileHandle -> mgmtInfo,0,SEEK_END);
filesize = ftell(fileHandle->mgmtInfo);
pageCnt = filesize/PAGE_SIZE;
fileHandle->totalNumPages = pageCnt;
RC_message="File Opened Successfully";
code = RC_OK;
}
return code;
}
//Implementation of the closePageFile interface
RC closePageFile (SM_FileHandle *fileHandle) {
/*The close page file function closes the file stream */
/*mgmtInfo stored the open file pointer previously*/
//If fclose returns 0 , then it means the file has been successfully closed
if(fclose(fileHandle->mgmtInfo)==0) {
RC_message="File closed successfully \n";
return RC_OK;
}
else {
return RC_FILE_NOT_FOUND;
}
}
RC destroyPageFile (char *filename) {
/*The destroy page file functions removes the file from the file system*/
//Try to remove the file with the remove function from the file system
if (remove(filename)==0) {
printf("File has been destroyed \n");
RC_message="File has been destroyed successfully.\n";
return RC_OK;
}
else {
return RC_FILE_NOT_FOUND;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//Validate File handle
RC validateFileHandle (SM_FileHandle *filehandle){
//Initialising the return code to OK
RC code = RC_OK;
//Checking if FileHandle is null
if(filehandle == NULL) {
//So The File handle given is null
//Setting the RC message as "Requested File is not initalized - filehandle == NULL"
RC_message = "Requested File is not initalized - filehandle == NULL";
//Setting return code to RC_FILE_HANDLE_NOT_INIT
code = RC_FILE_HANDLE_NOT_INIT;
}
//Check for file existance
else if (filehandle->mgmtInfo ==NULL) {
//So The File is not created or there in the database
RC_message = "File Not Found";
//Setting return code to RC_FILE_NOT_FOUND
code = RC_FILE_NOT_FOUND;
}
//Returning the code
return code;
}
//This Funtion validates the given File Handle and Page number to read
RC validateFile (int pageNum, SM_FileHandle *filehandle){
// Initialising the Return code to validate the input file handle
RC code = validateFileHandle(filehandle);
//If the code from "validateFileHandle(filehandle)" function is RC_OK, Then check whether the given page exists in the File
if ((code == RC_OK) && (pageNum+1) > filehandle->totalNumPages || pageNum < 0) {
//So The Pagenumber doesn't exist in the File
RC_message = "Requested page to be read doesn't exist";
//Setting the return code to RC_READ_NON_EXISTING_PAGE
code = RC_READ_NON_EXISTING_PAGE;
}
//Returning the code
return code;
}
//Reading the File with the given pagenumber, filehandle and Buffer
RC readBlock (int pageNum, SM_FileHandle *fileHandle, SM_PageHandle memPage){
//Initialise the Return code variable to Validate the page number and File handle
RC code = validateFile(pageNum, fileHandle);
//If the validation returns RC_OK, Then check whether Pagehandler is null
if((code == RC_OK) && (memPage !=NULL)) {
fseek(fileHandle->mgmtInfo,(((pageNum)*PAGE_SIZE)),SEEK_SET);//seeking to requested page number.
fread(memPage,sizeof(char),PAGE_SIZE,fileHandle->mgmtInfo);//reading to requested page.
fileHandle->curPagePos = (ftell(fileHandle->mgmtInfo)/PAGE_SIZE);//updating current page position
RC_message="File Read Successfull.";
}
//Returning the code
return code;
}
//This Function will return the integer containing the current page position of the file handle
int getBlockPos (SM_FileHandle *filehandle){
//Initialising the page position variable
int pos;
//Validate the given filehandle, If Validation returns RC_OK then check the current page position
if(validateFileHandle(filehandle) == RC_OK){
//Print the Position in the File and return the integer
printf("%d \n",filehandle->curPagePos);
pos = filehandle->curPagePos;
}
//Return the Position
return pos;
}
//Read the First Page in the File
RC readFirstBlock (SM_FileHandle *filehandle, SM_PageHandle memPage){
//Initializing page number to first page of the fuke handle
int pageNum = 0;
return readBlock(pageNum,filehandle, memPage);
}
//Read Previous page in the File
RC readPreviousBlock (SM_FileHandle *filehandle, SM_PageHandle memPage) {
//Initializing page number to current page position of the file handle - 1
int pageNum = getBlockPos(filehandle)-1;
return readBlock (pageNum,filehandle, memPage);
}
//Read current page in the File
RC readCurrentBlock (SM_FileHandle *filehandle, SM_PageHandle memPage){
//Initializing page number to current page position of the file handle
int pageNum = getBlockPos(filehandle);
return readBlock (pageNum,filehandle, memPage);
}
//Read Next page in the File
RC readNextBlock (SM_FileHandle *filehandle, SM_PageHandle memPage){
//Initializing page number to current page position of the file handle + 1
int pageNum = getBlockPos(filehandle)+1;
return readBlock (pageNum,filehandle, memPage);
}
//Read last page of the file
RC readLastBlock (SM_FileHandle *filehandle, SM_PageHandle memPage){
//Initializing page number to last page position of the file handle
int pageNum = (filehandle->totalNumPages)-1;
return readBlock (pageNum,filehandle, memPage);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
RC writeBlock (int pageNum, SM_FileHandle *fileHandle, SM_PageHandle memPage) {
// Initialising the Return code to validate the input file handle and the page number
RC code = validateFile(pageNum, fileHandle);
//If the Validation returns RC_OK, Then Check whether the buffer storage pointer is not null
if((code == RC_OK) && (memPage !=NULL)){
ensureCapacity(strlen(memPage)/PAGE_SIZE,fileHandle);
fseek(fileHandle->mgmtInfo, pageNum*PAGE_SIZE , SEEK_SET);
if(fwrite(memPage,PAGE_SIZE,1,fileHandle->mgmtInfo) == 1) {
fseek(fileHandle->mgmtInfo, (pageNum+1)*PAGE_SIZE , SEEK_SET);
fileHandle->curPagePos = (ftell(fileHandle->mgmtInfo)/PAGE_SIZE);
//fclose(filehandle->mgmtInfo);
RC_message="Data write successful.";
}
else
{
RC_message="Write Request Failed";
code = RC_WRITE_FAILED;
}
}
return code;
}
RC writeCurrentBlock (SM_FileHandle *fHandle, SM_PageHandle memPage) {
//Set the Page number to the current page position in the file and write to the page
return writeBlock(fHandle->curPagePos,fHandle,memPage);
}
RC appendEmptyBlock (SM_FileHandle *fileHandle) {
RC code = validateFileHandle(fileHandle);
if(code == RC_OK)
{
fseek(fileHandle->mgmtInfo,0,SEEK_END);
char *len = (char*)calloc(PAGE_SIZE,sizeof(char));
fwrite(len,PAGE_SIZE,sizeof(char),fileHandle->mgmtInfo);
free(len);
fileHandle->totalNumPages =(ftell(fileHandle->mgmtInfo)/PAGE_SIZE);
}
return code;
}
RC ensureCapacity(int numberOfPages, SM_FileHandle *fileHandle) {
RC code = validateFileHandle(fileHandle);
if((code == RC_OK) && (fileHandle->totalNumPages < numberOfPages)) {
for(;fileHandle->totalNumPages != numberOfPages;) {
appendEmptyBlock(fileHandle);
}
}
return code;
}