/[LeafOK_CVS]/pvpgn-1.7.4/src/tinycdb/cdb_make.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/tinycdb/cdb_make.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
Error occurred while calculating annotation data.
no message

1 /* basic cdb creation routines
2 *
3 * This file is a part of tinycdb package by Michael Tokarev, mjt@corpit.ru.
4 * Public domain.
5 */
6
7 #include "common/setup_before.h"
8 #include <stdio.h>
9 #ifdef STDC_HEADERS
10 # include <stdlib.h>
11 #else
12 # ifdef HAVE_MALLOC_H
13 # include <malloc.h>
14 # endif
15 #endif
16 #ifdef HAVE_STRING_H
17 # include <string.h>
18 #else
19 # ifdef HAVE_STRINGS_H
20 # include <strings.h>
21 # endif
22 # ifdef HAVE_MEMORY_H
23 # include <memory.h>
24 # endif
25 #endif
26 #include "common/xalloc.h"
27 #include "cdb_int.h"
28 #include "common/setup_after.h"
29
30 void
31 cdb_pack(unsigned num, unsigned char buf[4])
32 {
33 buf[0] = num & 255; num >>= 8;
34 buf[1] = num & 255; num >>= 8;
35 buf[2] = num & 255;
36 buf[3] = num >> 8;
37 }
38
39 int
40 cdb_make_start(struct cdb_make *cdbmp, FILE *fd)
41 {
42 memset(cdbmp, 0, sizeof(*cdbmp));
43 cdbmp->cdb_fd = fd;
44 cdbmp->cdb_dpos = 2048;
45 cdbmp->cdb_bpos = cdbmp->cdb_buf + 2048;
46 return 0;
47 }
48
49 static int
50 ewrite(FILE *fd, const char *buf, int len)
51 {
52 while(len) {
53 int l = fwrite(buf, 1, len, fd);
54 if (l < 0 && errno != EINTR)
55 return -1;
56 len -= l;
57 buf += l;
58 }
59 return 0;
60 }
61
62 int
63 _cdb_make_write(struct cdb_make *cdbmp, const char *ptr, unsigned len)
64 {
65 unsigned l = sizeof(cdbmp->cdb_buf) - (cdbmp->cdb_bpos - cdbmp->cdb_buf);
66 cdbmp->cdb_dpos += len;
67 if (len > l) {
68 memcpy(cdbmp->cdb_bpos, ptr, l);
69 if (ewrite(cdbmp->cdb_fd, cdbmp->cdb_buf, sizeof(cdbmp->cdb_buf)) < 0)
70 return -1;
71 ptr += l; len -= l;
72 l = len / sizeof(cdbmp->cdb_buf);
73 if (l) {
74 l *= sizeof(cdbmp->cdb_buf);
75 if (ewrite(cdbmp->cdb_fd, ptr, l) < 0)
76 return -1;
77 ptr += l; len -= l;
78 }
79 cdbmp->cdb_bpos = cdbmp->cdb_buf;
80 }
81 if (len) {
82 memcpy(cdbmp->cdb_bpos, ptr, len);
83 cdbmp->cdb_bpos += len;
84 }
85 return 0;
86 }
87
88 static int
89 cdb_make_finish_internal(struct cdb_make *cdbmp)
90 {
91 unsigned hcnt[256]; /* hash table counts */
92 unsigned hpos[256]; /* hash table positions */
93 struct cdb_rec *htab;
94 unsigned char *p;
95 struct cdb_rl *rl;
96 unsigned hsize;
97 unsigned t, i;
98
99 if (((0xffffffff - cdbmp->cdb_dpos) >> 3) < cdbmp->cdb_rcnt)
100 return errno = ENOMEM, -1;
101
102 /* count htab sizes and reorder reclists */
103 hsize = 0;
104 for (t = 0; t < 256; ++t) {
105 struct cdb_rl *rlt = NULL;
106 i = 0;
107 rl = cdbmp->cdb_rec[t];
108 while(rl) {
109 struct cdb_rl *rln = rl->next;
110 rl->next = rlt;
111 rlt = rl;
112 i += rl->cnt;
113 rl = rln;
114 }
115 cdbmp->cdb_rec[t] = rlt;
116 if (hsize < (hcnt[t] = i << 1))
117 hsize = hcnt[t];
118 }
119
120 /* allocate memory to hold max htable */
121 htab = (struct cdb_rec*)xmalloc((hsize + 2) * sizeof(struct cdb_rec));
122 if (!htab)
123 return errno = ENOENT, -1;
124 p = (unsigned char *)htab;
125 htab += 2;
126
127 /* build hash tables */
128 for (t = 0; t < 256; ++t) {
129 unsigned len, hi;
130 hpos[t] = cdbmp->cdb_dpos;
131 if ((len = hcnt[t]) == 0)
132 continue;
133 for (i = 0; i < len; ++i)
134 htab[i].hval = htab[i].rpos = 0;
135 for (rl = cdbmp->cdb_rec[t]; rl; rl = rl->next)
136 for (i = 0; i < rl->cnt; ++i) {
137 hi = (rl->rec[i].hval >> 8) % len;
138 while(htab[hi].rpos)
139 if (++hi == len)
140 hi = 0;
141 htab[hi] = rl->rec[i];
142 }
143 for (i = 0; i < len; ++i) {
144 cdb_pack(htab[i].hval, p + (i << 3));
145 cdb_pack(htab[i].rpos, p + (i << 3) + 4);
146 }
147 if (_cdb_make_write(cdbmp, p, len << 3) < 0) {
148 xfree(p);
149 return -1;
150 }
151 }
152 xfree(p);
153 if (cdbmp->cdb_bpos != cdbmp->cdb_buf &&
154 ewrite(cdbmp->cdb_fd, cdbmp->cdb_buf,
155 cdbmp->cdb_bpos - cdbmp->cdb_buf) != 0)
156 return -1;
157 p = cdbmp->cdb_buf;
158 for (t = 0; t < 256; ++t) {
159 cdb_pack(hpos[t], p + (t << 3));
160 cdb_pack(hcnt[t], p + (t << 3) + 4);
161 }
162 rewind(cdbmp->cdb_fd);
163 if (ewrite(cdbmp->cdb_fd, p, 2048) != 0)
164 return -1;
165
166 return 0;
167 }
168
169 static void
170 cdb_make_free(struct cdb_make *cdbmp)
171 {
172 unsigned t;
173 for(t = 0; t < 256; ++t) {
174 struct cdb_rl *rl = cdbmp->cdb_rec[t];
175 while(rl) {
176 struct cdb_rl *tm = rl;
177 rl = rl->next;
178 xfree(tm);
179 }
180 }
181 }
182
183 int
184 cdb_make_finish(struct cdb_make *cdbmp)
185 {
186 int r = cdb_make_finish_internal(cdbmp);
187 cdb_make_free(cdbmp);
188 return r;
189 }
190

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1