Skip to content

Commit e429a19

Browse files
committed
Merge branch 'file_org'
2 parents 6701cfe + c3f7697 commit e429a19

File tree

12 files changed

+635
-0
lines changed

12 files changed

+635
-0
lines changed

File Organization/Hash FO/hashFO.c

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
#include "hashFO.h"
2+
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
7+
/**
8+
* Creates a .hash file with empty buckets.
9+
* Returns 0 if success, -1 if error.
10+
*/
11+
int createEmptyHashFile(char *hashFile){
12+
FILE *hFile;
13+
Bucket b;
14+
int i, nBuckets;
15+
16+
if(NULL == (hFile = fopen(hashFile, "wb")))
17+
return -1;
18+
19+
20+
memset(&b, 0, sizeof(Bucket));
21+
nBuckets = BUCKETS + OVERFLOW_BUCKETS;
22+
23+
for(i=0; i<nBuckets; i++){
24+
fwrite(&b, sizeof(Bucket), 1, hFile);
25+
}
26+
27+
fclose(hFile);
28+
return 0;
29+
}
30+
31+
32+
/**
33+
* Creates a .hash file from a .dat file. It reads people info from
34+
* a .dat file and inserts it to buckets in .hash file.
35+
* It returns:
36+
* - (-1) if params error
37+
* - (-2) if cannot open .dat file
38+
* - number of overflowing registers that where inserted.
39+
*/
40+
int createHashFromBinaryFile(char *binaryFile, char *hashFile){
41+
if(-1 == createEmptyHashFile(hashFile))
42+
return -1;
43+
44+
FILE *inFile, *outFile;
45+
if(NULL == (inFile = fopen(binaryFile, "rb"))) return -2;
46+
47+
Person p;
48+
Bucket b;
49+
int nOverflows = 0;
50+
int insertedBucket;
51+
52+
while(fread(&p, sizeof(Person), 1, inFile)){
53+
insertedBucket = insertRegister(&p, hashFile);
54+
55+
if(insertedBucket >= BUCKETS)
56+
nOverflows++;
57+
}
58+
return nOverflows;
59+
}
60+
61+
62+
/**
63+
* Reads, interprets and prints a .hash file to see how data is stored.
64+
* Returns the total number of buckets the .hash file stores (including
65+
* buckets in overflowing area), or -1 if cannot open the .hash file.
66+
*/
67+
int readHashFile(char *hashFile){
68+
FILE *hFile;
69+
Bucket b;
70+
int i,j,n;
71+
72+
if(NULL == (hFile = fopen(hashFile, "rb")))
73+
return -1;
74+
75+
rewind(hFile);
76+
77+
i = 0;
78+
fread(&b, sizeof(Bucket), 1, hFile);
79+
while(!feof(hFile)){
80+
for(j=0; j<CAPACITY; j++){
81+
if(j == 0){
82+
printf("\x1b[36;1m==============================================================\n");
83+
printf("\x1b[33;3;4mBucket %2d (%02d registers assigned)\n\x1b[0m",i, b.size);
84+
}
85+
86+
if(j < b.size)
87+
printf("\t\t\t%-8s %-19s %-19s %-19s %-11s\n", b.registers[j].dni, b.registers[j].name,
88+
b.registers[j].surname1,b.registers[j].surname2,b.registers[j].province);
89+
else
90+
printf("\n");
91+
}
92+
93+
i++;
94+
fread(&b, sizeof(Bucket), 1, hFile);
95+
}
96+
97+
printf("\x1b[36;1m==============================================================\n\x1b[0m");
98+
fclose(hFile);
99+
return i;
100+
}
101+
102+
103+
/**
104+
* Searches for a register in a .hash file given a dni.
105+
* It returns:
106+
* - (-1) if params error
107+
* - (-2) if cannot open .hash file
108+
* - (-3) if dni is not stored in .hash file
109+
* - bucket number where dni has been found
110+
*/
111+
int searchRegister(char *dni, char *hashFile, Person *p){
112+
if(dni == NULL || hashFile == NULL || p == NULL)
113+
return -1;
114+
115+
FILE *hFile;
116+
if(NULL == (hFile = fopen(hashFile, "rb")))
117+
return -2;
118+
119+
int i;
120+
Bucket b;
121+
122+
//Move to the bucket where dni should be stored according to the hashFile
123+
fseek(hFile, HASH_BUCKET(atoi(dni)), SEEK_SET);
124+
fread(&b, sizeof(Bucket), 1, hFile);
125+
126+
//Look if the dni is in that bucket. If it is not in the cube:
127+
// - If bucket size < CAPACITY -> dni is not stored anywhere
128+
// - If bucket size >= CAPACITY -> dni might be stored in overflow zone
129+
for(i=0; i<CAPACITY && i<b.size; i++){
130+
if(strcmp(b.registers[i].dni, dni) == 0){
131+
*p = b.registers[i];
132+
return HASH(atoi(dni));
133+
}
134+
}
135+
136+
if(b.size < CAPACITY)
137+
return -3;
138+
else{
139+
int bucketReaded;
140+
141+
//Move to overflow zone
142+
fseek(hFile, OVERFLOW_ZONE, SEEK_SET);
143+
144+
bucketReaded = 0;
145+
while(fread(&b, sizeof(Bucket), 1, hFile)){
146+
for(i=0; i<CAPACITY && i<b.size; i++){
147+
if(strcmp(b.registers[i].dni, dni) == 0){
148+
*p = b.registers[i];
149+
return BUCKETS + bucketReaded;
150+
}
151+
}
152+
153+
//If the last bucket is reached (last is not full) and
154+
// dni was not found, dni is not stored anywhere.
155+
if(b.size < CAPACITY)
156+
return -3;
157+
158+
bucketReaded++;
159+
}
160+
}
161+
}
162+
163+
164+
/**
165+
* Inserts a new register (person) in a .hash file.
166+
* - (-1) if params error
167+
* - (-2) if cannot open .hash file
168+
* - (-3) if there is no more available space to store people
169+
* - bucket number where dni has been stored if success
170+
*/
171+
int insertRegister(Person *p, char *hashFile){
172+
if(p == NULL || hashFile == NULL)
173+
return -1;
174+
175+
FILE *hFile;
176+
if(NULL == (hFile = fopen(hashFile, "rb+"))){
177+
return -2;
178+
}
179+
180+
Bucket b;
181+
182+
//Move pointer to the cube where the register in going to be
183+
// stored, according to the DNI hash
184+
fseek(hFile, HASH_BUCKET(atoi(p->dni)), SEEK_SET);
185+
186+
//Reads the cube from the file:
187+
// - If bucket size < CAPACITY -> Bucket has space to store the registers
188+
// - If bucket size >= CAPACITY -> Bucket has no space, register is stores in overflow zone.
189+
fread(&b, sizeof(Bucket), 1, hFile);
190+
191+
if(b.size < CAPACITY){
192+
b.registers[b.size] = *p;
193+
(b.size)++;
194+
195+
//Move pointer back to the bucket again and overwrite it
196+
fseek(hFile, -sizeof(Bucket), SEEK_CUR);
197+
fwrite(&b, sizeof(Bucket), 1, hFile);
198+
199+
fclose(hFile);
200+
return HASH(atoi(p->dni));
201+
202+
}else{
203+
int i, bucketToRead;
204+
205+
//Increment size and rewrite the register that is full.
206+
b.size++;
207+
fseek(hFile, -sizeof(Bucket), SEEK_CUR);
208+
fwrite(&b, sizeof(Bucket), 1, hFile);
209+
210+
//Move to overflow zone and search for a empty space to
211+
// store the register. If there is no more space available,
212+
// it returns -3.
213+
fseek(hFile, OVERFLOW_ZONE, SEEK_SET);
214+
215+
bucketToRead = 0;
216+
fread(&b, sizeof(Bucket), 1, hFile);
217+
218+
while(!(b.size < CAPACITY)){
219+
bucketToRead++;
220+
if(bucketToRead == OVERFLOW_BUCKETS){
221+
fclose(hFile);
222+
return -3;
223+
}
224+
225+
fread(&b, sizeof(Bucket), 1, hFile);
226+
}
227+
228+
229+
//If there is a bucket with available space, inserts the register
230+
// and overwrites the bucket in the file.
231+
b.registers[b.size] = *p;
232+
fseek(hFile, -sizeof(Bucket), SEEK_CUR);
233+
fwrite(&b, sizeof(Bucket), 1, hFile);
234+
235+
//Finally, increments the number of registers assigned in all
236+
// overflow buckets located before the bucket where the register
237+
// was saved
238+
fseek(hFile, OVERFLOW_ZONE, SEEK_SET);
239+
for(i=0; i<=bucketToRead; i++){
240+
//Read cube
241+
fread(&b, sizeof(Bucket), 1, hFile);
242+
//Increment size
243+
b.size++;
244+
//Overwrite cube
245+
fseek(hFile, -sizeof(Bucket), SEEK_CUR);
246+
fwrite(&b, sizeof(Bucket), 1, hFile);
247+
}
248+
249+
fclose(hFile);
250+
return (BUCKETS + bucketToRead);
251+
}
252+
}
253+
254+

File Organization/Hash FO/hashFO.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#ifndef __HASH_FO_H__
2+
#define __HASH_FO_H__
3+
4+
#define CAPACITY 5
5+
#define BUCKETS 20
6+
#define OVERFLOW_BUCKETS 4
7+
8+
//Auxiliar "functions"
9+
#define HASH(K) ((K)%BUCKETS)
10+
#define HASH_BUCKET(K) ((HASH(K))*sizeof(Bucket))
11+
#define OVERFLOW_ZONE (BUCKETS*sizeof(Bucket))
12+
13+
14+
/**
15+
* Each struct is stored in a bucket according to a hash. This hash is
16+
* calculated with the dni of the person using modulus formula:
17+
* hash = dni % BUCKETS
18+
*
19+
* Each calculated hash is related to a specific bucket where that person
20+
* is/is going to be stored.
21+
*
22+
* If all (20) buckets all full, there is a auxiliar zone to store more people.
23+
* This is called "Overflow zone", and has a capacity of 4 more buckets. This zone
24+
* is a secuential area that stores people when the bucket that corresponds to the hash
25+
* calculated with a dni is full. When a person is stored in this zone, the size of the
26+
* cube where the person should have been stored is increased even if it is stored in
27+
* the overflow zone. This lets the user know that there should be more people than there
28+
* are in the full bucket, and that they are stored in the overflow zone.
29+
*
30+
* If both the (20)buckets and overflow zone are full, no more people can be inserted.
31+
*/
32+
33+
typedef struct person{
34+
char dni[9];
35+
char name[19];
36+
char surname1[19];
37+
char surname2[19];
38+
char province[11];
39+
}Person;
40+
41+
42+
typedef struct bucket{
43+
Person registers[CAPACITY];
44+
int size;
45+
}Bucket;
46+
47+
48+
//Create hash file
49+
int createEmptyHashFile(char *hashFile);
50+
int createHashFromBinaryFile(char *binaryFile, char *hashFile);
51+
52+
//Functions
53+
int readHashFile(char *hashFile);
54+
int searchRegister(char *dni, char *hashFile, Person *p);
55+
int insertRegister(Person *p, char *hashFile);
56+
57+
58+
//TODO: deleteRegister function (reduce bucket size and relocate overflow zone registers
59+
// that should have been in the buckets)
60+
#endif

File Organization/Hash FO/main.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "hashFO.h"
2+
3+
#include <stdio.h>
4+
#include <string.h>
5+
6+
7+
int main(void){
8+
int i, nOverflows;
9+
FILE *f;
10+
Person p;
11+
char hashFile[12] = "people.hash";
12+
char dni[9];
13+
14+
nOverflows = createHashFromBinaryFile("people.dat", hashFile);
15+
i = readHashFile(hashFile);
16+
17+
printf("\n\n\x1b[33;3;4mTotal Cubes:\x1b[0;35;1m %d\x1b[0m \n", i);
18+
printf("\x1b[33;3;4mOverflowing registers:\x1b[0;35;1m %d\x1b[0m \n\n", nOverflows);
19+
20+
//Search registers
21+
strcpy(dni,"7389298"); //Exists in a bucket
22+
i = searchRegister(dni, hashFile, &p);
23+
switch(i){
24+
case -1: printf("\x1b[31;1mError in searchRegister\x1b[0m \n"); break;
25+
case -2: printf("\x1b[31;1mError cannot open file in searchRegister!!!\x1b[0m \n"); break;
26+
case -3: printf("\x1b[31;1mCannot find person with dni %s\x1b[0m \n", dni); break;
27+
default: printf("\x1b[32;1mRegister finded in BUCKET %d:",i);
28+
printf("\x1b[0;36;1m %s %s %s %s %s \x1b[0m \n", p.dni, p.name, p.surname1,
29+
p.surname2,p.province);
30+
}
31+
32+
33+
strcpy(dni,"7219752"); //Exists in a overflow zone
34+
i = searchRegister(dni, hashFile, &p);
35+
switch(i){
36+
case -1: printf("\x1b[31;1mError in searchRegister\x1b[0m \n"); break;
37+
case -2: printf("\x1b[31;1mError cannot open file in searchRegister!!!\x1b[0m \n"); break;
38+
case -3: printf("\x1b[31;1mCannot find person with dni %s\x1b[0m \n", dni); break;
39+
default: printf("\x1b[32;1mRegister finded in BUCKET %d:",i);
40+
printf("\x1b[0;36;1m %s %s %s %s %s \x1b[0m \n", p.dni, p.name, p.surname1,
41+
p.surname2,p.province);
42+
}
43+
44+
45+
strcpy(dni,"12345678"); //Dont exist
46+
i = searchRegister(dni, hashFile, &p);
47+
switch(i){
48+
case -1: printf("\x1b[31;1mError in searchRegister\x1b[0m \n"); break;
49+
case -2: printf("\x1b[31;1mError cannot open file in searchRegister!!!\x1b[0m \n"); break;
50+
case -3: printf("\x1b[31;1mCannot find person with dni %s\x1b[0m \n", dni); break;
51+
default: printf("\x1b[32;1mRegister finded in BUCKET %d:",i);
52+
printf("\x1b[0;36;1m %s %s %s %s %s \x1b[0m \n", p.dni, p.name, p.surname1,
53+
p.surname2,p.province);
54+
}
55+
56+
57+
//Insert register
58+
printf("\n");
59+
Person newPerson = {"12345678","Hi","im","new","Salamanca"}; //Inserts in overflow zone
60+
i = insertRegister(&newPerson, hashFile);
61+
switch(i){
62+
case -1: printf("\x1b[31;1mError in insertRegister\x1b[0m \n"); break;
63+
case -2: printf("\x1b[31;1mError cannot open file in insertRegister!!!\x1b[0m \n"); break;
64+
case -3: printf("\x1b[31;1mNo more space available to insert\x1b[0m \n"); break;
65+
default: printf("\x1b[32;1mRegister inserted in BUCKET %d \n",i);
66+
}
67+
68+
69+
Person otherNewPerson = {"19493800","Other","new","person","Salamanca"}; //Inserts in bucket 0
70+
i = insertRegister(&otherNewPerson, hashFile);
71+
switch(i){
72+
case -1: printf("\x1b[31;1mError in insertRegister\x1b[0m \n"); break;
73+
case -2: printf("\x1b[31;1mError cannot open file in insertRegister!!!\x1b[0m \n"); break;
74+
case -3: printf("\x1b[31;1mNo more space available to insert\x1b[0m \n"); break;
75+
default: printf("\x1b[32;1mRegister inserted in BUCKET %d \n",i);
76+
}
77+
78+
//readHashFile(hashFile);
79+
80+
printf("\n");
81+
return 0;
82+
}

0 commit comments

Comments
 (0)