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