| 1 | |
|---|
| 2 | /* cihsh.c - included from ciupd.c |
|---|
| 3 | */ |
|---|
| 4 | |
|---|
| 5 | //#include <string.h> |
|---|
| 6 | //#include "cisis.h" /* CISIS Interface header file */ |
|---|
| 7 | |
|---|
| 8 | LONGX hashzero(char *table, LONGX maxprim, int tabwidth) |
|---|
| 9 | { |
|---|
| 10 | size_t size=maxprim*(tabwidth+1); |
|---|
| 11 | memset(table,0x00,size); |
|---|
| 12 | return((LONGX)size); |
|---|
| 13 | } |
|---|
| 14 | |
|---|
| 15 | #if CICPP |
|---|
| 16 | char * RECSTRU :: hashalloc(LONGX classes, int tabwidth, LONGX *maxprimp) |
|---|
| 17 | #else /* CICPP */ |
|---|
| 18 | char *hashalloc(LONGX classes, int tabwidth, LONGX *maxprimp) |
|---|
| 19 | #endif /* CICPP */ |
|---|
| 20 | { |
|---|
| 21 | LONGX maxprim=classes; |
|---|
| 22 | char *p; |
|---|
| 23 | LONGX maxdiv,divid; |
|---|
| 24 | int done=0; |
|---|
| 25 | while (!done) { |
|---|
| 26 | maxdiv=maxprim/2; |
|---|
| 27 | for (divid=2; divid<maxdiv; divid++) |
|---|
| 28 | if (!(maxprim % divid)) { maxprim--; break; } |
|---|
| 29 | if (divid >= maxdiv) done=1; |
|---|
| 30 | } |
|---|
| 31 | p=loadfile(NULL,'@',"",NULL,maxprim*(tabwidth+1),'\0'); |
|---|
| 32 | hashzero(p,maxprim,tabwidth); |
|---|
| 33 | *maxprimp=maxprim; |
|---|
| 34 | return(p); |
|---|
| 35 | } |
|---|
| 36 | |
|---|
| 37 | #if CICPP |
|---|
| 38 | LONGX RECSTRU :: hashindex(char *table, LONGX maxprim, int tabwidth, char *keyp, int keylen, int *foundp, int installit) |
|---|
| 39 | #else /* CICPP */ |
|---|
| 40 | LONGX hashindex(char *table, LONGX maxprim, int tabwidth, char *keyp, int keylen, int *foundp, int installit) |
|---|
| 41 | #endif /* CICPP */ |
|---|
| 42 | { |
|---|
| 43 | unsigned LONGX hashv=0; |
|---|
| 44 | unsigned char *hashvp=(unsigned char *)&hashv; |
|---|
| 45 | int hashvloop=sizeof(hashv); |
|---|
| 46 | int loop=hashvloop; |
|---|
| 47 | int left; |
|---|
| 48 | unsigned char *p=hashvp; |
|---|
| 49 | unsigned char *kp=(unsigned char *)keyp; |
|---|
| 50 | int found=0; |
|---|
| 51 | LONGX hidx,x; |
|---|
| 52 | char *h; |
|---|
| 53 | |
|---|
| 54 | if (keylen > tabwidth) keylen=tabwidth; |
|---|
| 55 | for (left=keylen; left--; ) { |
|---|
| 56 | *p ^= *kp; p++; kp++; loop--; |
|---|
| 57 | if (!loop) { p=hashvp; loop=hashvloop; } |
|---|
| 58 | } |
|---|
| 59 | x=hidx=hashv%maxprim; |
|---|
| 60 | tabwidth++; /* (tabwidth+1) */ |
|---|
| 61 | h=table+hidx*tabwidth; |
|---|
| 62 | while (*h) { |
|---|
| 63 | if (!memcmp(h,keyp,keylen)) if (!h[keylen]) { found=1; break; } |
|---|
| 64 | if (++hidx == maxprim) { hidx=0; h=table; } |
|---|
| 65 | else h+=tabwidth; |
|---|
| 66 | if (hidx == x) fatal("cihsh/hashindex/overflow"); |
|---|
| 67 | } |
|---|
| 68 | if (!found) if (installit) memcpy(h,keyp,keylen); |
|---|
| 69 | *foundp=found; |
|---|
| 70 | return(hidx); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | |
|---|
| 74 | #if CICPP |
|---|
| 75 | char * RECSTRU :: bsrchalloc(LONGX classes, int tabwidth, LONGX *tabentries) |
|---|
| 76 | #else /* CICPP */ |
|---|
| 77 | char *bsrchalloc(LONGX classes, int tabwidth, LONGX *tabentries) |
|---|
| 78 | #endif /* CICPP */ |
|---|
| 79 | { |
|---|
| 80 | char *p; |
|---|
| 81 | p=loadfile(NULL,'@',"",NULL,classes*(tabwidth+1),'\0'); |
|---|
| 82 | hashzero(p,classes,tabwidth); |
|---|
| 83 | *tabentries=0; |
|---|
| 84 | return(p); |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | #if CICPP |
|---|
| 88 | LONGX RECSTRU :: bsrchstore(char *table, LONGX classes, LONGX *tabentries, int tabwidth, char *keyp, int keylen) |
|---|
| 89 | #else /* CICPP */ |
|---|
| 90 | LONGX bsrchstore(char *table, LONGX classes, LONGX *tabentries, int tabwidth, char *keyp, int keylen) |
|---|
| 91 | #endif /* CICPP */ |
|---|
| 92 | { |
|---|
| 93 | char *h; |
|---|
| 94 | int w=tabwidth+1; |
|---|
| 95 | LONGX entries= *tabentries; |
|---|
| 96 | LONGX index; |
|---|
| 97 | |
|---|
| 98 | if (keylen > tabwidth) keylen=tabwidth; |
|---|
| 99 | |
|---|
| 100 | if (entries >= classes) fatal("cihsh/bsrchstore/overflow"); |
|---|
| 101 | |
|---|
| 102 | h=table+w*(entries-1); |
|---|
| 103 | if (memcmp(keyp,h,w) <= 0) fatal("cihsh/bsrchstore/unsorted"); |
|---|
| 104 | |
|---|
| 105 | h+=w; index=entries; |
|---|
| 106 | memcpy(h,keyp,keylen); (*tabentries)++; |
|---|
| 107 | |
|---|
| 108 | return(index); |
|---|
| 109 | } |
|---|
| 110 | |
|---|
| 111 | #if CICPP |
|---|
| 112 | LONGX RECSTRU :: bsrchindex(char *table, LONGX tabentries, int tabwidth, char *keyp, int keylen, int *foundp) |
|---|
| 113 | #else /* CICPP */ |
|---|
| 114 | LONGX bsrchindex(char *table, LONGX tabentries, int tabwidth, char *keyp, int keylen, int *foundp) |
|---|
| 115 | #endif /* CICPP */ |
|---|
| 116 | { |
|---|
| 117 | LONGX i1,i2,i; |
|---|
| 118 | char *h; |
|---|
| 119 | int w=tabwidth+1; |
|---|
| 120 | int found=0; |
|---|
| 121 | LONGX index; |
|---|
| 122 | |
|---|
| 123 | if (keylen > tabwidth) keylen=tabwidth; |
|---|
| 124 | |
|---|
| 125 | i1=0; |
|---|
| 126 | i2=tabentries-1; |
|---|
| 127 | while (i1 <= i2) { |
|---|
| 128 | i=(i1+i2)/2; |
|---|
| 129 | h= table+w*i; |
|---|
| 130 | //if (memcmp(keyp,h,keylen) == 0) if (!h[keylen]) { found=1; index=i; break; } |
|---|
| 131 | //if (memcmp(keyp,h,keylen) < 0) i2=i-1; else i1=i+1; |
|---|
| 132 | |
|---|
| 133 | if (memcmp(keyp,h,keylen) == 0) if (!h[keylen]) { found=1; index=i; break; } |
|---|
| 134 | |
|---|
| 135 | if (memcmp(keyp,h,keylen) < 0) i2=i-1; |
|---|
| 136 | else |
|---|
| 137 | if (memcmp(keyp,h,keylen) > 0) i1=i+1; |
|---|
| 138 | else |
|---|
| 139 | if (h[keylen]) i2=i-1; else fatal("cihsh/bsrchindex/bug"); |
|---|
| 140 | } |
|---|
| 141 | |
|---|
| 142 | if (!found) index=(-1); |
|---|
| 143 | *foundp=found; |
|---|
| 144 | return(index); |
|---|
| 145 | } |
|---|