Source Code in C
1: /*include files*/
2: #include <stdio.h>
3: #include <stdlib.h> 4: #include <string.h>
5: #include <ctype.h> 6:
7: 8: #define HTE_OK 1
9: #define MAXOPENFILES 20 10: #define BLOCKSIZE 512
11: #define MAXSCANS 20 12: #define STRING 'c'
13: #define FLOAT 'f' 14: #define INTEGER 'i'
15: #define EQUAL 1 16: #define NOTEQUAL 2
17: #define HTE_EOF NULL 18: /************************************************************************************/
19: 20: /*domh me plirofories gia to arxeio katakermatismou*/
21: typedef struct 22: {
23: FILE *fp; 24: char fieldtype1,fieldtype2,valid;
25: int fieldlength1,fieldlength2,nbuckets,diag; 26: }blockheader;
27: 28: /*domh gia th diadikasia anzhthshs*/
29: typedef struct 30: {
31: int filedesc,valid,op,bucket; 32: void *value;
33: long where; 34: long offset;
35: }scan_struct; 36:
37: /*katholikes metavlites*/ 38: char *buf;//pinakas buf gia thn apothikeysh twn blocks
39: int HT_errno;//metavliti gia ta lathi 40: blockheader header[20];//pinakas domwn gia kathe anoixto arxeio
41: scan_struct scan[20];//pinakas domwn gia kathe sarwsh 42:
43: /**********************************************************************************/ 44: /*Dilwseis synarthsewn*/
45: void HT_Init(void); 46: int HT_CreateIndex(char *fileName,char attrType1,int attrLength1,char attrType2,int attrLength2,int buckets);
47: int HT_DestroyIndex(char *fileName); 48: int HT_OpenIndex (char *fileName);
49: int HT_CloseIndex (int fileDesc); 50: int HT_InsertEntry(int fileDesc,void *value1,void *value2);
51: int HT_DeleteEntry(int fileDesc,void *value1,void *value2); 52: int HT_OpenIndexScan(int fileDesc,int op,void *value);
53: void *HT_FindNextEntry(int scanDesc); 54: int HT_CloseIndexScan(int scanDesc);
55: void HT_PrintError(char *errString); 56: int hash_fn(const void *item, int n,char itemtype,int length);
57: int sygkrisi(void *value1,void *value2,char fieldtype,int length); 58: /***********************************************************************/
59: 60: /****************************************************************************************
61: *Synarthsh: HT_Init() 62: *Skopos: Arxikopoiei oles tis eswterikes domes dedomenwn pou xreiazontai gia thn xrhsh
63: katakermatismou. 64: *Episterei: Tipota
65: ******************************************************************************************/ 66: void HT_Init(void)
67: { 68: int i;
69: 70: buf = (char *)malloc(BLOCKSIZE);//pinakas buf gia thn apothikeysh twn blocks
71: 72: //arxikopoihsh pinaka gia ola ta anoixta arxeia katakermatismou
73: for(i=1;i<=MAXOPENFILES;i++) 74: {
75: header[i].fieldtype1='\0';//typos prwtou pediou 76: header[i].fieldtype2='\0';//typos deyterou pediou
77: header[i].fieldlength1=0;//mikos prwtou pediou 78: header[i].fieldlength2=0;//mikos deyterou pediou
79: header[i].fp=NULL;//anagnwristiko tou arxeiou 80: header[i].nbuckets=0;//arithmos koubadwn
81: header[i].valid=0;//pshfio taytopoihshs anoixtou arxeiou 82: header[i].diag=0;//pshfio diagrafis
83: } 84:
85: //arxikopoihsh pinaka gia ola tis anoixtes sarwseis arxeiwn 86: for(i=0;i<MAXSCANS;i++)
87: { 88: scan[i].filedesc=-1;//anagnwristiko ths theshs tou arxeiou katakermatismou
89: scan[i].op=0;//telesths sygkrishs 90: scan[i].valid=0;//pshfio taytopoihshs egkyrhs sarwshs
91: scan[i].value=0;//timhsygrishs 92: scan[i].offset=-1;//eggrafes pou exoun sarwthei
93: scan[i].where=-1;//thesi pou vriskomaste sto arxeio katakermatismou 94: scan[i].bucket=0;//arithmos kouva.
95: } 96:
97: } 98: /*************************************************************************/
99: 100: /****************************************************************************************
101: *Synarthsh: HT_CreateIndex() 102: *Skopos: Dhmiourgei ena kainourio adeio arxeio katakermatismou,arxikopoiontas kai
103: apothikeyontas mesa sto arxeio tis aparaithtes metavlites katallila . 104: *Epistefei: HTE_OK se periptwsh epityxias h kapoio kwdiko lathous
105: ******************************************************************************************/ 106: int HT_CreateIndex( char *fileName,char attrType1,int attrLength1,char attrType2,int attrLength2,int buckets)
107: { 108: int i,j,*iptr;
109: FILE *file; /*Αναγνωριστικό αρχείου.*/ 110:
111: //anoigma arxeiou gia grapsimo 112: if( (file = fopen( fileName, "wb" )) == NULL )
113: { 114: //periptwsh lathous kata to anoigma
115: printf( "The file %s was not opened\n",fileName ); 116: HT_errno=-1;
117: return HT_errno; 118: }
119: else 120: {
121: for(i=0;i<BLOCKSIZE;i++) 122: {
123: buf[i]=0; 124: }
125: buf[0]=attrType1;//1o byte:typos 1ou pediou 126: buf[1]=attrType2;//2o byte:typos 2ou pediou
127: iptr=(int *)(buf+2*sizeof(char)); 128: iptr[0]=attrLength1;//3o byte:mhkos 1ou pediou
129: iptr[1]=attrLength2;//7o byte:mikos 2ou pediou 130: iptr[2]=buckets;//11o byte:arithmos kouvadwn
131: fwrite(buf,BLOCKSIZE,1,file);//grapsimo tou prwtou block me xrhsimes plirofories 132: //dhmiourgia kouvadwn
133: for(j=0;j<buckets;j++) 134: {
135: for(i=0;i<BLOCKSIZE;i++) 136: {
137: buf[i]=0; 138: }
139: //arxikes times kathe kouba 140: iptr=(int *)buf;
141: iptr[0]=-1; //1o byte tou kouva:deikths sto block yperxeilhshs 142: iptr[1]=0; //2o bytetou kouva:arithmos eggrafon
143: fwrite(buf,BLOCKSIZE,1,file); 144: }
145: } 146: if( fclose( file) ) /*Κλείνουμε το αρχείο με έλεγχο για την επιτυχία κλεισίματος.*/
147: { 148: printf( "The file %s was not closed\n",fileName );
149: HT_errno=-1; 150: return HT_errno; /*Σε περίπτωση αποτυχίας στο κλείσιμο του αρχείου η συνάρτηση επιστρέφει την τιμή -1.*/
151: } 152: return HTE_OK; /*Αν η συνάρτηση τερματίσει επιτυχώς, επιστρέφει την τιμή HTE_OK.*/
153: } 154:
155: /*************************************************************************/ 156:
157: /**************************************************************************************** 158: *Synarthsh: HT_DestroyIndex()
159: *Skopos: Katastrefei to arxeio katakermatismou me onoma "filename",svinontas ola ta 160: dedomena tou.
161: *Epistefei: HTE_OK se periptwsh epityxias h kapoio kwdiko lathous 162: ******************************************************************************************/
163: int HT_DestroyIndex(char *fileName) 164: {
165: //daiagrafi arxeiou katakermatismou 166: if( remove( fileName ) == -1 )
167: {//an synevh lathos epistrefei -1 168: printf("Could not delete %s",fileName );
169: HT_errno=-1; 170: return HT_errno;
171: } 172: else//se periptwsh epityxias epistrefei HTE_OK
173: return HTE_OK; 174:
175: } 176: /*************************************************************************/
177: /**************************************************************************************** 178: *Synarthsh: HT_OpenIndex()
179: *Skopos: Anoigei to arxeio filename kai apothikeyei oles tis xrhsimes plirofories gia ayto 180: se kapoia thesi tou pinaka me ta anoixta arxeia.
181: *Epistefei: Thn thesi tou pinaka pou antistoixei sto arxeio ayto h kapoio kwdiko lathous 182: ******************************************************************************************/
183: int HT_OpenIndex (char *fileName) 184: {
185: int i=0,*iptr; 186: FILE *file; /*Αναγνωριστικό αρχείου.*/
187: 188: //Anoigma arxeiou gia diavasma
189: if( (file = fopen( fileName, "rb+" )) == NULL ) 190: {
191: //apotyxia anoigmatos kaiepisrofi -1 192: printf( "The file %s was not opened\n",fileName );
193: HT_errno=-1; 194: return HT_errno;
195: } 196: else
197: { 198: fread(buf,BLOCKSIZE,1,file);//diavasma 1ou block me xrhsimes plirofories
199: //psaximo gia kenh thesi sto pinaka anoixtwn arxeiwn 200: while(header[i].valid!=0)
201: i++; 202: if(i==MAXOPENFILES-1)//Exoun anoixtei hdh MAXOPENFILES arxeia kai den yparxei
203: { //kenh thesi sto pinaka 204: printf("Den mporoun na anoixtoun pano apo %d arxeia mazi!\n",MAXOPENFILES);
205: HT_errno=0; 206: return HT_errno;
207: } 208: header[i].fieldtype1=buf[0];//typos prwtou pediou
209: header[i].fieldtype2=buf[1];//typos deyterou pediou 210: iptr=(int *)(buf+2*sizeof(char));
211: header[i].fieldlength1=*iptr;//mikos prwtou pediou 212: header[i].fieldlength2=*(iptr+1);//mikos deyterou pediou
213: header[i].nbuckets=*(iptr+2);//aritmos koubadwn 214: header[i].valid=1;//pshfio taytopoihshs anoixtou arxeiou
215: header[i].fp=file;//anagnwristiko tou arxeiou 216: header[i].diag=0;//den exei gine diagrafi
217: 218: }
219: return i;//epistrofi ths thesis ston pinaka 220: }
221: /*************************************************************************/ 222:
223: 224:
225: /**************************************************************************************** 226: *Synarthsh: HT_CloseIndex()
227: *Skopos: Kleinei to arxeio pou antistoixei sth thesi fileDesc kai svhnei thn 228: sygkekrimenh kataxwrhsh apo ton pinaka me ta anoixta arxeia.
229: *Epistefei: HTE_OK se periptwsh epityxias h kapoio kwdiko lathous 230: ******************************************************************************************/
231: int HT_CloseIndex (int fileDesc/* αριθμός που αντιστοιχεί στο ανοιχτό αρχείο 232: */)
233: { 234: if( fclose(header[fileDesc].fp)) /*Κλείνουμε το αρχείο με έλεγχο για την επιτυχία κλεισίματος.*/
235: { 236: printf( "The file %d was not closed\n",fileDesc);
237: HT_errno=-1; 238: return HT_errno; /*Σε περίπτωση αποτυχίας στο κλείσιμο του αρχείου η συνάρτηση επιστρέφει την τιμή -1.*/
239: } 240: //svhsimo ths kataxwrhshs
241: header[fileDesc].fieldtype1='\0'; 242: header[fileDesc].fieldtype2='\0';
243: header[fileDesc].fieldlength1=0; 244: header[fileDesc].fieldlength2=0;
245: header[fileDesc].fp=NULL; 246: header[fileDesc].nbuckets=0;
247: header[fileDesc].valid=0; 248: header[fileDesc].diag=0;
249: 250: return HTE_OK; /*Αν η συνάρτηση τερματίσει επιτυχώς, επιστρέφει την τιμή HTE_OK.*/
251: } 252: /********************************************************************************/
253: 254: /****************************************************************************************
255: *Synarthsh: HT_InsertEntry() 256: *Skopos: Eisagei thn eggrafi (value1,value2) sto arxeio katakermatismou pou antistoixei
257: sth thesi fileDesc,me vasi to pedio kleidivalue1. 258: *Epistefei: HTE_OK se periptwsh epityxias h kapoio kwdiko lathous
259: ******************************************************************************************/ 260: int HT_InsertEntry(int fileDesc,void *value1,void *value2)
261: { 262: int *records,*next,nbucket,recsize,*overnext,*overrecord,*iptr;
263: char *overflow,*cptr; 264: float *fptr;
265: long eofile,where; 266:
267: next=(int *)malloc(sizeof(int)); 268: overflow=(char*)malloc(BLOCKSIZE);
269: 270: //epilogi kouva pou prepei na topotheththei h eggrafi me vasi th synarthsh katakermatismou
271: nbucket=hash_fn(value1,header[fileDesc].nbuckets,header[fileDesc].fieldtype1,header[fileDesc].fieldlength1); 272:
273: //entopismos antistoixou kouva mesa sto arxeio kai diavasma tou 1ou block 274: fseek(header[fileDesc].fp,(nbucket+1)*BLOCKSIZE,SEEK_SET);
275: fread(buf,BLOCKSIZE,1,header[fileDesc].fp); 276:
277: next=(int *)buf;//deikths sto block yperxeilhshs 278: records=(int *)(buf+(sizeof(int)));//arithmos eggrafwn
279: recsize=header[fileDesc].fieldlength1+header[fileDesc].fieldlength2;//megethos kathe eggrafhs 280:
281: 282: while(1)
283: { 284: //Apothikeysi ths thesis tou block sto arxeio
285: where=ftell(header[fileDesc].fp); 286: where-=BLOCKSIZE;
287: 288: //elegxos an yparxei xwros gia akoma mia eggrafi sto sygkekrimeno block
289: if(((recsize*((*records)+1))>(BLOCKSIZE-2*sizeof(int)))) 290: {
291: //An den yparxei elegxos dhmiourgias block yperxeilhshs 292: if(*next==-1)
293: { 294: //Den yparxei block yperxeilhshs,ara dhmiourgia kainourioublock sto
295: //telos tou arxeiou 296: fseek(header[fileDesc].fp,0,SEEK_END);//entopismos telous tou arxeiou
297: eofile=ftell(header[fileDesc].fp); 298: *next=eofile;//apothikeysi ths theshs tou neou block
299: 300: //Grapsimo tou prohgoumenou block sth swsth thesi me ton neo deikth
301: //yperxeilhshs 302: fseek(header[fileDesc].fp,where,SEEK_SET);
303: fwrite(buf,BLOCKSIZE,1,header[fileDesc].fp); 304:
305: //Arxikopoihsh timwn tou neou block 306: overnext=(int *)overflow;
307: *overnext=-1; 308: overrecord=(int *)overflow+1;
309: *overrecord=1; 310: //Apothikeysh ths eggrafis analoga me ton typo kathe pediou
311: switch(header[fileDesc].fieldtype1) 312: {
313: case 'c': 314: cptr=(char *)(overflow+2*sizeof(int));
315: strncpy(cptr,(char*)value1,header[fileDesc].fieldlength1); 316: break;
317: case 'f': 318: fptr=(float *)(overflow +2*sizeof(int));
319: *fptr = *((float *)value1); 320: break;
321: case 'i': 322: iptr=(int *)(overflow +2*sizeof(int));
323: *iptr = *((int *)value1); 324: break;
325: } 326: switch(header[fileDesc].fieldtype2)
327: { 328: case 'c':
329: cptr=(char*)(overflow+2*sizeof(int)+header[fileDesc].fieldlength1); 330: strncpy(cptr,(char *)value2,header[fileDesc].fieldlength2);
331: break; 332: case 'f':
333: fptr=(float *)(overflow +2*sizeof(int)+header[fileDesc].fieldlength1); 334: *fptr = *((float *)value2);
335: break; 336: case 'i':
337: iptr=(int *)(overflow +2*sizeof(int)+header[fileDesc].fieldlength1); 338: *iptr = *((int *)value2);
339: break; 340: }
341: //grapsimo sto telos tou arxeiou tou neou block yperxeilhshs 342: fseek(header[fileDesc].fp,eofile,SEEK_SET);
343: fwrite(overflow,BLOCKSIZE,1,header[fileDesc].fp); 344: free(overflow);
345: return HTE_OK; 346: }
347: //Exei hdh dhmiourghthei block yperxeilhshs. 348: //Entopismos kai diavasma tou block aytou
349: fseek(header[fileDesc].fp,*next,SEEK_SET); 350: fread(buf,BLOCKSIZE,1,header[fileDesc].fp);
351: next=(int *)buf;//neos deikths 352: records=(int *)(buf+(sizeof(int)));//neos aritmos eggrafwn
353: } 354: else
355: break;//Den exei gemisei to block kai tha eisagoume th nea eggrafi 356:
357: } 358:
359: //Apothikeysh ths eggrafis analoga me ton typo kathe pediou 360: switch(header[fileDesc].fieldtype1)
361: { 362: case 'c':
363: cptr=(char *)(buf+2*sizeof(int)+recsize*(*records)); 364: strncpy(cptr,(char*)value1,header[fileDesc].fieldlength1);
365: break; 366: case 'f':
367: fptr=(float *)(buf+2*sizeof(int)+recsize*(*records)); 368: *fptr = *((float *)value1);
369: break; 370: case 'i':
371: iptr=(int *)(buf+2*sizeof(int)+recsize*(*records)); 372: *iptr = *((int *)value1);
373: break; 374: }
375: switch(header[fileDesc].fieldtype2) 376: {
377: case 'c': 378: cptr=(char *)(buf+2*sizeof(int)+recsize*(*records)+header[fileDesc].fieldlength1);
379: strncpy(cptr,(char*)value2,header[fileDesc].fieldlength2); 380: break;
381: case 'f': 382: fptr=(float *)(buf+2*sizeof(int)+recsize*(*records)+header[fileDesc].fieldlength1);
383: *fptr = *((float *)value2); 384: break;
385: case 'i': 386: iptr=(int *)(buf+2*sizeof(int)+recsize*(*records)+header[fileDesc].fieldlength1);
387: *iptr = *((int *)value2); 388: break;
389: } 390: (*records)++;//ayxhsh tou aritmou eggrafwn
391: //Grapsimo sthn katallhlh thesh tou enhmerwmenou block 392: fseek(header[fileDesc].fp,where,SEEK_SET);
393: fwrite(buf,BLOCKSIZE,1,header[fileDesc].fp); 394: return HTE_OK;
395: } 396:
397: 398: /********************************************************************************/
399: /**************************************************************************************** 400: *Synarthsh: HT_DeleteEntry()
401: *Skopos: Diagrafei thn eggrafi (value1,value2) ap'to arxeio katakermatismou pou antistoixei 402: sth thesi fileDesc.
403: *Epistefei: HTE_OK se periptwsh epityxias h kapoio kwdiko lathous 404: ******************************************************************************************/
405: int HT_DeleteEntry(int fileDesc,void *value1,void *value2) 406: {
407: 408: int i,vrethike,*records,*next,nbucket,recsize;
409: char *cptr; 410: long where;
411: 412: next=(int *)malloc(sizeof(int));
413: //Epilogi kouva pou vrisketai h eggrafi me vasi th synarthsh katakermatismou 414: nbucket=hash_fn(value1,header[fileDesc].nbuckets,header[fileDesc].fieldtype1,header[fileDesc].fieldlength1);
415: //megethos kathe eggrafis 416: recsize=header[fileDesc].fieldlength1+header[fileDesc].fieldlength2;
417: //thesi mesa sto arxeio tou kouva 418: *next=(nbucket+1)*BLOCKSIZE;
419: 420: while(1)
421: { 422: //entopismos ths theshs tou block sto arxeio
423: fseek(header[fileDesc].fp,*next,SEEK_SET); 424: where=ftell(header[fileDesc].fp);
425: fread(buf,BLOCKSIZE,1,header[fileDesc].fp); 426:
427: next=(int *)buf;//deikths yperxeilhshs 428: records=(int *)(buf+(sizeof(int)));//arithmos eggrafwn
429: //An den yparxoun eggrafes sto block 430: if(*records==0)
431: { 432: if(*next != -1)//an yparxei block yperxeilhshs synexise
433: continue; 434: else
435: { //Alliws den yparxei h eggrafi 436: printf("Den yparxei h eggrafi!\n");
437: break; 438: }
439: } 440: else
441: { 442: //Exetash olwn twn eggrafwn sto block
443: cptr=buf+(2*sizeof(int)); 444: for(i=0;i<(*records);i++)
445: { 446: //sygkrisi tou 1ou pediou ths eggrafis me value1
447: vrethike=sygkrisi(value1,cptr,header[fileDesc].fieldtype1,header[fileDesc].fieldlength1); 448: if(vrethike==1)//an einai idio
449: { 450: cptr+=header[fileDesc].fieldlength1;
451: //sygkrisi tou 2ou pediou ths eggrafis me value2 452: vrethike=sygkrisi(value2,cptr,header[fileDesc].fieldtype2,header[fileDesc].fieldlength2);
453: if(vrethike==1)//an einai idio-svhsimo ths eggrafis 454: {
455: (*records)--; 456: //antigrafi ths teleytaias eggrafis sth thesi ths diagrafomenis
457: cptr=buf+2*sizeof(int)+((*records)*recsize); 458: memcpy((buf+2*sizeof(int)+i*recsize),cptr,recsize);
459: //Grasimo tou neou enhmerwmenou block sthn katallhlh thesi 460: fseek(header[fileDesc].fp,where,SEEK_SET);
461: fwrite(buf,BLOCKSIZE,1,header[fileDesc].fp); 462: header[fileDesc].diag=1;//enhmerwsh oti egine diagrafi
463: return HTE_OK; 464: }
465: cptr-=header[fileDesc].fieldlength1; 466: }
467: cptr+=recsize;//proxorame sthn epomenh eggrafi 468: }
469: } 470: //An den yparexei block yperxeilhshs,den yparxei h eggrafi
471: if(*next==-1) 472: {
473: break; 474: }
475: } 476: HT_errno=-1;
477: return HT_errno; 478: }
479: 480: /********************************************************************************/
481: 482: /****************************************************************************************
483: *Synarthsh: HT_OpenIndexScan() 484: *Skopos: Anoigei mia sarwsh pou antistoixei sth thesi tou pinaka fileDesc kai enhmerwnei
485: thn antistoixh kataxwrhsh ston pinaka sarwsewn.H sarwsh vriskei oles tis eggrafes 486: pou oi times sto pedio kleidi ikanopoioun ton telesti syggrisis op me thn timh
487: ths value1. 488: *Epistefei:thn thesi ston pinaka sarwsewn ths sarwshs h kapoio kwdiko lathous
489: ******************************************************************************************/ 490: int HT_OpenIndexScan(int fileDesc,int op,void *value)
491: { 492: int i=0;
493: 494: //Eyresh kenhs thesis ston pinaka sarwsewn
495: while(scan[i].valid!=0) 496: i++;
497: if(i==MAXSCANS-1)//mono MAXSCANS sarwseis einai anoixtes taytoxrona 498: {
499: printf("O pinakas saroseon einai gematos!\n"); 500: HT_errno=-1;
501: return HT_errno; 502: }
503: scan[i].filedesc=fileDesc;//anagnwristiko arxeiou katakermatismou 504: scan[i].op=op;//telesths sygkrishs
505: scan[i].valid=1;//pshfio endeixhs anoixths sarwshs 506: scan[i].value=value;//timh sygkrishs
507: scan[i].where=-1;//thesi sto arxeio pou vrisketai h sarwsh 508: scan[i].offset=0;//arithmos eggrafwn pou exoun sarwthei
509: scan[i].bucket=0;//arithmos kouva. 510:
511: return i; 512: }
513: /********************************************************************************/ 514:
515: /**************************************************************************************** 516: *Synarthsh: HT_FindNextEntry()
517: *Skopos: Ektelei th sarwsh pou antistoixei sth kataxwrhsh scanDesc tou pinaka,vriskontas 518: kathe fora thn epomenh eggrafi.
519: *Epistefei:Thn timh tou 2ou pediou ths epomenhs eggrafis pou ikanopoiei th synthikh 520: ths sarwshs h kapoio kwdiko lathous
521: ******************************************************************************************/ 522: void *HT_FindNextEntry(int scanDesc)
523: { 524: int i,vrethike,*records,*next,nbucket,recsize,fileDesc,op,bucket;
525: char *cptr; 526: long where;
527: 528: next=(int *)malloc(sizeof(int));
529: 530: fileDesc=scan[scanDesc].filedesc;//anagnwristiko arxeiou
531: recsize=header[fileDesc].fieldlength1+header[fileDesc].fieldlength2;//megethos eggrafwn 532: op=scan[scanDesc].op;//telesths sygkrishs ths sarwshs
533: 534: //Epilogh tou kouva pou pithanws vrisketai h timh sygkrishs value
535: nbucket=hash_fn(scan[scanDesc].value,header[fileDesc].nbuckets,header[fileDesc].fieldtype1,header[fileDesc].fieldlength1); 536: bucket=scan[scanDesc].bucket;//kouvas sarwshs pou vriskomaste
537: 538: while(bucket!=header[fileDesc].nbuckets)//oso yparxoun kouvades gia anazhthsh
539: { 540: if(op==NOTEQUAL && bucket!=nbucket)//periptwsh mh isothtas kai o kouvas sarwshs
541: {//den periexei thntimh sygkrishs 542:
543: if(scan[scanDesc].where==-1)//prwth sarwsh 544: {
545: //xekinhma sarwshs apo thn arxh tou arxeiou 546: *next=(bucket+1)*BLOCKSIZE;
547: fseek(header[fileDesc].fp,*next,SEEK_SET); 548: }
549: else 550: {
551: //xekinhma sarwshs apo thn thesi pou vriskomastan 552: fseek(header[fileDesc].fp,scan[scanDesc].where,SEEK_SET);
553: } 554:
555: while(1) 556: {
557: where=ftell(header[fileDesc].fp); 558: fread(buf,BLOCKSIZE,1,header[fileDesc].fp);
559: next=(int *)buf;//deikths yperxeilhshs 560: records=(int *)(buf+(sizeof(int)));//arithmos eggrafwn sto block
561: 562: if(*records==0)//An den yparxoun eggrafes
563: { 564: if(*next != -1)//An yparxei block yperxeilhshs
565: continue;//synexise thnanazhthsh se ayto 566: else
567: {//den yparxei h eggrafi 568: printf("Den yparxei h eggrafi!\n");
569: break; 570: }
571: } 572: else
573: {//Yparxoun eggrafes sto block 574: if(header[fileDesc].diag==1)//An exei ginei diagrafi,meta
575: {//thn prohgoumenh sarwsh,xekinhma apo thn arxh 576: scan[scanDesc].offset=0;
577: } 578: header[fileDesc].diag=0;
579: 580: //anazhthsh apo thn eggrafi ths prohgoumenhs sarwshs ews to telos tou block
581: for(i=scan[scanDesc].offset;i<(*records);i++) 582: {
583: //oles oi eggrafes tou block den einai ises me thn timh sygkrishs value1 584: cptr=buf+2*sizeof(int)+scan[scanDesc].offset*recsize;
585: cptr+=header[fileDesc].fieldlength1;//deytero pedio 586: scan[scanDesc].where=where;//apothikeysi thesis
587: scan[scanDesc].offset=i+1;//apothikeysi teleytaias eggrafis pou sarwthike 588: return (void *)cptr;
589: } 590: }
591: if(*next==-1)//den yparxoun alles eggrafes ston kouva ayto 592: {
593: break; 594: }
595: fseek(header[fileDesc].fp,*next,SEEK_SET);//phgaine sto block yperxeilhshs 596: scan[scanDesc].offset=0;//xekinhma apo thn arxh
597: } 598: scan[scanDesc].bucket++;//epomenos kouvas
599: scan[scanDesc].where=-1;//xekinhma apo thn arxh tou kouva 600: scan[scanDesc].offset=0;
601: } 602: if(op==EQUAL || bucket==nbucket)//Periptwsh isothtas
603: {//kai mh isothtas alla h timh sygrishs vrisketai ston kouva sarwshs 604:
605: if(scan[scanDesc].where==-1)//prwth sarwshtou arxeiou 606: {//xekinhma apo thn arxh tou katallhlou kouva
607: *next=(nbucket+1)*BLOCKSIZE; 608: fseek(header[fileDesc].fp,*next,SEEK_SET);
609: } 610: else
611: {//xekinhma apo thn teleytaia sarwsh 612: fseek(header[fileDesc].fp,scan[scanDesc].where,SEEK_SET);
613: } 614:
615: while(1) 616: {
617: where=ftell(header[fileDesc].fp); 618: fread(buf,BLOCKSIZE,1,header[fileDesc].fp);
619: next=(int *)buf;//deikths sto block yperxeilhshs 620: records=(int *)(buf+(sizeof(int)));//arithmos eggrafwn
621: 622:
623: if(*records==0)//An den yparxoun eggrafes 624: {
625: if(*next != -1)//An yparxei block yperxeilhshs 626: continue;//synexise thnanazhthsh se ayto
627: else 628: {
629: printf("Den yparxei h eggrafi!\n"); 630: break;
631: } 632: }
633: else 634: {//Yparxoun eggrafes sto block
635: if(header[fileDesc].diag==1) 636: {//An exei ginei endiamesh diagrafi xekina apo thn arxh tou block
637: scan[scanDesc].offset=0; 638: }
639: header[fileDesc].diag=0; 640:
641: //anazhthsh se oles tis eggrafes tou block 642: cptr=buf+2*sizeof(int)+scan[scanDesc].offset*recsize;
643: for(i=scan[scanDesc].offset;i<(*records);i++) 644: {
645: //elgxos sygkrishs prwtou pediou 646: vrethike=sygkrisi(scan[scanDesc].value,cptr,header[fileDesc].fieldtype1,header[fileDesc].fieldlength1);
647: if(vrethike==1) 648: {
649: if(op==EQUAL)//An prokeitai gia isothta 650: {
651: //epestrepse to deytero pedio 652: cptr+=header[fileDesc].fieldlength1;
653: scan[scanDesc].where=where; 654: scan[scanDesc].offset=i+1;
655: return (void *)cptr; 656: }
657: 658: }
659: else 660: {//den idio to prwto pedio me to value
661: if(op==NOTEQUAL)//periptwsh mh isothtas 662: {
663: //epestrepse to deytero pedio 664: cptr+=header[fileDesc].fieldlength1;
665: scan[scanDesc].where=where; 666: scan[scanDesc].offset=i+1;
667: return (void *)cptr; 668: }
669: } 670: cptr+=recsize;
671: } 672: }
673: if(*next==-1)//an den yparxei allo block 674: {//teleiwse h anazhthsh ston kouva nbucket
675: break; 676: }
677: fseek(header[fileDesc].fp,*next,SEEK_SET); 678: scan[scanDesc].offset=0;
679: } 680: if(op==NOTEQUAL)//periptwsh mh isothtas
681: { 682: scan[scanDesc].bucket++;//proxorise ston epomeno kouva
683: scan[scanDesc].where=-1;//xekinhma apo thn arxh ths sarwshs 684: scan[scanDesc].offset=0;
685: } 686: }
687: if(op==EQUAL)//o kouvas den periexei allh eggrafi pou ikanopoiei 688: {//thn isothta
689: return HTE_EOF; 690: }
691: bucket=scan[scanDesc].bucket; 692: }
693: return HTE_EOF; 694: }
695: 696: /********************************************************************************/
697: 698: /****************************************************************************************
699: *Synarthsh: HT_CloseIndexScan() 700: *Skopos: Termtizei th sarwsh pou antistoixei sth kataxwrhsh scanDesc tou pinaka,svinontas
701: kai aythn th kataxwrhsh 702: *Epistefei:HTE_OK se perptwsh epityxias h kapoio kwdiko lathous
703: ******************************************************************************************/ 704: int HT_CloseIndexScan(int scanDesc)
705: { 706: scan[scanDesc].filedesc=-1;
707: scan[scanDesc].offset=0; 708: scan[scanDesc].op=0;
709: scan[scanDesc].valid=0; 710: scan[scanDesc].value=0;
711: scan[scanDesc].where=-1; 712: return HTE_OK;
713: } 714: /********************************************************************************/
715: /**************************************************************************************** 716: *Synarthsh: HT_PrintError()
717: *Skopos:Typwnei to mhnyma pou deixenei h parametros errString kai ton kwdiko lathous 718: *Epistefei:Tipota
719: ******************************************************************************************/ 720: void HT_PrintError(char *errString)
721: { 722: printf("%s",errString);
723: printf("Error Number:%d\n",HT_errno); 724: }
725: /********************************************************************************/ 726:
727: /**************************************************************************************** 728: *Synarthsh: hash_fn()
729: *Skopos:Katakermatizei thn timh tou item,analoga me ton typo tou se kapoion apo tous 730: kouvades
731: *Epistefei:Ton arithmo tou kouva,apo 0-n 732: ******************************************************************************************/
733: int hash_fn(void *item, int n,char itemtype,int length) 734: {
735: char *cptr; 736: float *fptr;
737: int *iptr; 738:
739: if(itemtype=='c') 740: {
741: cptr=(char *)item; 742: return (cptr[length%3])%n;//to ypoloipo kapoiou xarakthra me ton aritmo kouvadwn
743: } 744: if(itemtype=='f')
745: { 746: fptr=(float *)item;
747: iptr=(int *)fptr; 748: return *iptr%n;//to ypoloipo ths timhs me ton arithmo kouvadwn
749: } 750: if(itemtype=='i')
751: { 752: iptr=(int *)item;
753: return *iptr%n;//to ypoloipo ths timhs me ton arithmo kouvadwn 754: }
755: HT_errno=-1; 756: return HT_errno;
757: } 758:
759: 760:
761: /**************************************************************************************** 762: *Synarthsh: Sygkrisi()
763: *Skopos: Elegxei thn isothta ths timhs value1 me aythn ths value2 analoga me to 764: typo fieldtype.
765: *Epistefei:1 se periptwsh isothtas,alliws 0 766: ******************************************************************************************/
767: int sygkrisi(void *value1,void *value2,char fieldtype,int length) 768: {
769: char *cptr1,*cptr2; 770: int *iptr1,*iptr2;
771: float *fptr1,*fptr2; 772: switch(fieldtype)
773: { 774: case 'c':
775: cptr1=(char *)value1; 776: cptr2=(char *)value2;
777: if(strncmp(cptr1,cptr2,length)==0) 778: return 1;
779: else 780: return 0;
781: case 'f': 782: fptr1=(float *)value1;
783: fptr2=(float *)value2; 784: if(*fptr1==*fptr2)
785: return 1; 786: else
787: return 0; 788: case 'i':
789: iptr1=(int *)value1; 790: iptr2=(int *)value2;
791: if(*iptr1==*iptr2) 792: return 1;
793: else 794: return 0;
795: default: 796: return 0;
797: } 798: }