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