Hashing in C

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: }