s/qmail 4.2.29a
Next generation secure email transport
Loading...
Searching...
No Matches
strset.c
Go to the documentation of this file.
1#include "strset.h"
2#include "str.h"
3#include "byte.h"
4#include "alloc.h"
5
6uint32 strset_hash(char *s)
7{
8 unsigned char ch;
9 uint32 h;
10
11 h = 5381LL;
12
13 while ((ch = *s)) {
14 h = ((h << 5) + h) ^ ch;
15 ++s;
16 }
17 return h;
18}
19
21{
22 int h;
23 set->mask = 15;
24 set->n = 0;
25 set->a = 10;
26
27 set->first = (int *) alloc(sizeof(int) * (set->mask + 1));
28 if (!set->first) return 0;
29 set->p = (strset_list *) alloc(sizeof(strset_list) * set->a);
30 if (!set->p) { alloc_free(set->first); return 0; }
31 set->x = (char **) alloc(sizeof(char *) * set->a);
32 if (!set->x) { alloc_free(set->p); alloc_free(set->first); return 0; }
33
34 for (h = 0; h <= set->mask; ++h)
35 set->first[h] = -1;
36
37 return 1;
38}
39
40char *strset_in(strset *set,char *s)
41{
42 uint32 h;
43 strset_list *sl;
44 int i;
45 char *xi;
46
47 h = strset_hash(s);
48 i = set->first[h & set->mask];
49
50 while (i >= 0) {
51 sl = set->p + i;
52 if (sl->h == h) {
53 xi = set->x[i];
54 if (!str_diff(xi,s)) return xi;
55 }
56 i = sl->next;
57 }
58 return 0;
59}
60
61int strset_add(strset *set,char *s)
62{
63 uint32 h;
64 int n;
65 strset_list *sl;
66
67 n = set->n;
68
69 if (n == set->a) {
70 int newa;
71 strset_list *newp;
72 char **newx;
73
74 newa = n + 10 + (n >> 3);
75 newp = (strset_list *) alloc(sizeof(strset_list) * newa);
76 if (!newp) return 0;
77 newx = (char **) alloc(sizeof(char *) * newa);
78 if (!newx) { alloc_free(newp); return 0; }
79
80 byte_copy(newp,sizeof(strset_list) * n,set->p);
81 byte_copy(newx,sizeof(char *) * n,set->x);
82 alloc_free(set->p);
83 alloc_free(set->x);
84 set->p = newp;
85 set->x = newx;
86 set->a = newa;
87
88 if (n + n + n > set->mask) {
89 int newmask;
90 int *newfirst;
91 int i;
92 uint32 h;
93
94 newmask = set->mask + set->mask + 1;
95 newfirst = (int *) alloc(sizeof(int) * (newmask + 1));
96 if (!newfirst) return 0;
97
98 for (h = 0; h <= newmask; ++h)
99 newfirst[h] = -1;
100
101 for (i = 0; i < n; ++i) {
102 sl = set->p + i;
103 h = sl->h & newmask;
104 sl->next = newfirst[h];
105 newfirst[h] = i;
106 }
107
108 alloc_free(set->first);
109 set->first = newfirst;
110 set->mask = newmask;
111 }
112 }
113
114 h = strset_hash(s);
115
116 sl = set->p + n;
117 sl->h = h;
118 h &= set->mask;
119 sl->next = set->first[h];
120 set->first[h] = n;
121 set->x[n] = s;
122 set->n = n + 1;
123
124 return 1;
125}
void h(char *, int, int, int)
Definition: install.c:15
char * strset_in(strset *set, char *s)
Definition: strset.c:40
int strset_add(strset *set, char *s)
Definition: strset.c:61
uint32 strset_hash(char *s)
Definition: strset.c:6
int strset_init(strset *set)
Definition: strset.c:20
int next
Definition: strset.h:9
uint32 h
Definition: strset.h:8
Definition: strset.h:14
int * first
Definition: strset.h:18
int n
Definition: strset.h:16
int a
Definition: strset.h:17
int mask
Definition: strset.h:15
char ** x
Definition: strset.h:20
strset_list * p
Definition: strset.h:19