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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide 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
no message

1 sysadm 1.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