File Coverage

x2p/hash.c
Criterion Covered Total %
statement 0 72 0.0
branch n/a
condition n/a
subroutine n/a
total 0 72 0.0


line stmt bran cond sub time code
1           /* hash.c
2           *
3           * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002,
4           * 2005 by Larry Wall and others
5           *
6           * You may distribute under the terms of either the GNU General Public
7           * License or the Artistic License, as specified in the README file.
8           */
9            
10           #include
11           #include "EXTERN.h"
12           #include "a2p.h"
13           #include "util.h"
14            
15           #ifdef NETWARE
16           char *savestr(char *str);
17           #endif
18            
19           STR *
20 0         hfetch(HASH *tb, char *key)
21           {
22           char *s;
23           int i;
24           int hash;
25           HENT *entry;
26            
27 0         if (!tb)
28           return NULL;
29 0         for (s=key, i=0, hash = 0;
30 0         /* while */ *s;
31 0         s++, i++, hash *= 5) {
32 0         hash += *s * coeff[i];
33           }
34 0         entry = tb->tbl_array[hash & tb->tbl_max];
35 0         for (; entry; entry = entry->hent_next) {
36 0         if (entry->hent_hash != hash) /* strings can't be equal */
37 0         continue;
38 0         if (strNE(entry->hent_key,key)) /* is this it? */
39 0         continue;
40 0         return entry->hent_val;
41           }
42           return NULL;
43           }
44            
45           bool
46 0         hstore(HASH *tb, char *key, STR *val)
47           {
48           char *s;
49           int i;
50           int hash;
51           HENT *entry;
52           HENT **oentry;
53            
54 0         if (!tb)
55           return FALSE;
56 0         for (s=key, i=0, hash = 0;
57 0         /* while */ *s;
58 0         s++, i++, hash *= 5) {
59 0         hash += *s * coeff[i];
60           }
61            
62 0         oentry = &(tb->tbl_array[hash & tb->tbl_max]);
63           i = 1;
64            
65 0         for (entry = *oentry; entry; i=0, entry = entry->hent_next) {
66 0         if (entry->hent_hash != hash) /* strings can't be equal */
67 0         continue;
68 0         if (strNE(entry->hent_key,key)) /* is this it? */
69 0         continue;
70           /*NOSTRICT*/
71 0         safefree(entry->hent_val);
72 0         entry->hent_val = val;
73 0         return TRUE;
74           }
75           /*NOSTRICT*/
76 0         entry = (HENT*) safemalloc(sizeof(HENT));
77            
78 0         entry->hent_key = savestr(key);
79 0         entry->hent_val = val;
80 0         entry->hent_hash = hash;
81 0         entry->hent_next = *oentry;
82 0         *oentry = entry;
83            
84 0         if (i) { /* initial entry? */
85 0         tb->tbl_fill++;
86 0         if ((tb->tbl_fill * 100 / (tb->tbl_max + 1)) > FILLPCT)
87 0         hsplit(tb);
88           }
89            
90           return FALSE;
91           }
92            
93           void
94 0         hsplit(HASH *tb)
95           {
96 0         const int oldsize = tb->tbl_max + 1;
97 0         int newsize = oldsize * 2;
98           int i;
99           HENT **a;
100           HENT **b;
101           HENT *entry;
102           HENT **oentry;
103            
104 0         a = (HENT**) saferealloc((char*)tb->tbl_array, newsize * sizeof(HENT*));
105 0         memset(&a[oldsize], 0, oldsize * sizeof(HENT*)); /* zero second half */
106 0         tb->tbl_max = --newsize;
107 0         tb->tbl_array = a;
108            
109 0         for (i=0; i
110 0         if (!*a) /* non-existent */
111 0         continue;
112 0         b = a+oldsize;
113 0         for (oentry = a, entry = *a; entry; entry = *oentry) {
114 0         if ((entry->hent_hash & newsize) != i) {
115 0         *oentry = entry->hent_next;
116 0         entry->hent_next = *b;
117 0         if (!*b)
118 0         tb->tbl_fill++;
119 0         *b = entry;
120 0         continue;
121           }
122           else
123 0         oentry = &entry->hent_next;
124           }
125 0         if (!*a) /* everything moved */
126 0         tb->tbl_fill--;
127           }
128 0         }
129            
130           HASH *
131 0         hnew(void)
132           {
133 0         HASH *tb = (HASH*)safemalloc(sizeof(HASH));
134            
135 0         tb->tbl_array = (HENT**) safemalloc(8 * sizeof(HENT*));
136 0         tb->tbl_fill = 0;
137 0         tb->tbl_max = 7;
138           hiterinit(tb); /* so each() will start off right */
139 0         memset(tb->tbl_array, 0, 8 * sizeof(HENT*));
140 0         return tb;
141           }
142            
143           int
144 0         hiterinit(HASH *tb)
145           {
146 0         tb->tbl_riter = -1;
147 0         tb->tbl_eiter = (HENT*)NULL;
148 0         return tb->tbl_fill;
149           }