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