cdbmake_add.c (2267B)
1 #include "alloc.h" 2 #include "cdbmake.h" 3 4 void cdbmake_init(cdbm) 5 struct cdbmake *cdbm; 6 { 7 cdbm->head = 0; 8 cdbm->split = 0; 9 cdbm->hash = 0; 10 cdbm->numentries = 0; 11 } 12 13 int cdbmake_add(struct cdbmake *cdbm, uint32 h, uint32 p) 14 { 15 struct cdbmake_hplist *head; 16 17 head = cdbm->head; 18 if (!head || (head->num >= CDBMAKE_HPLIST)) { 19 head = (struct cdbmake_hplist *) alloc(sizeof(struct cdbmake_hplist)); 20 if (!head) return 0; 21 head->num = 0; 22 head->next = cdbm->head; 23 cdbm->head = head; 24 } 25 head->hp[head->num].h = h; 26 head->hp[head->num].p = p; 27 ++head->num; 28 ++cdbm->numentries; 29 return 1; 30 } 31 32 int cdbmake_split(struct cdbmake *cdbm) 33 { 34 int i; 35 uint32 u; 36 uint32 memsize; 37 struct cdbmake_hplist *x; 38 39 for (i = 0;i < 256;++i) 40 cdbm->count[i] = 0; 41 42 for (x = cdbm->head;x;x = x->next) { 43 i = x->num; 44 while (i--) 45 ++cdbm->count[255 & x->hp[i].h]; 46 } 47 48 memsize = 1; 49 for (i = 0;i < 256;++i) { 50 u = cdbm->count[i] * 2; 51 if (u > memsize) 52 memsize = u; 53 } 54 55 memsize += cdbm->numentries; /* no overflow possible up to now */ 56 u = (uint32) 0 - (uint32) 1; 57 u /= sizeof(struct cdbmake_hp); 58 if (memsize > u) return 0; 59 60 cdbm->split = (struct cdbmake_hp *) alloc(memsize * sizeof(struct cdbmake_hp)); 61 if (!cdbm->split) return 0; 62 63 cdbm->hash = cdbm->split + cdbm->numentries; 64 65 u = 0; 66 for (i = 0;i < 256;++i) { 67 u += cdbm->count[i]; /* bounded by numentries, so no overflow */ 68 cdbm->start[i] = u; 69 } 70 71 for (x = cdbm->head;x;x = x->next) { 72 i = x->num; 73 while (i--) 74 cdbm->split[--cdbm->start[255 & x->hp[i].h]] = x->hp[i]; 75 } 76 77 return 1; 78 } 79 80 uint32 cdbmake_throw(cdbm,pos,b) 81 struct cdbmake *cdbm; 82 uint32 pos; 83 int b; 84 { 85 uint32 len; 86 uint32 j; 87 uint32 count; 88 struct cdbmake_hp *hp; 89 uint32 where; 90 91 count = cdbm->count[b]; 92 93 len = count + count; /* no overflow possible */ 94 cdbmake_pack(cdbm->final + 8 * b,pos); 95 cdbmake_pack(cdbm->final + 8 * b + 4,len); 96 97 if (len) { 98 for (j = 0;j < len;++j) 99 cdbm->hash[j].h = cdbm->hash[j].p = 0; 100 101 hp = cdbm->split + cdbm->start[b]; 102 for (j = 0;j < count;++j) { 103 where = (hp->h >> 8) % len; 104 while (cdbm->hash[where].p) 105 if (++where == len) 106 where = 0; 107 cdbm->hash[where] = *hp++; 108 } 109 } 110 111 return len; 112 }