aboutsummaryrefslogtreecommitdiff
path: root/src/fetchkeys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fetchkeys.c')
-rw-r--r--src/fetchkeys.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/src/fetchkeys.c b/src/fetchkeys.c
new file mode 100644
index 0000000..32f0199
--- /dev/null
+++ b/src/fetchkeys.c
@@ -0,0 +1,320 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <gdbm.h>
4#include <string.h>
5#include <unistd.h>
6#include <limits.h>
7#include <errno.h>
8#include <signal.h>
9#include <assert.h>
10#include <sys/time.h>
11#include <sys/stat.h>
12
13static unsigned long
14get_size (char const *str)
15{
16 char *p;
17 unsigned long n, m;
18
19 errno = 0;
20 n = strtoul (str, &p, 10);
21 if (errno)
22 {
23 perror (str);
24 exit (1);
25 }
26 switch (*p)
27 {
28 case 0:
29 m = 1;
30 break;
31
32 case 'k':
33 case 'K':
34 p++;
35 m = 1024;
36 break;
37
38 case 'm':
39 case 'M':
40 p++;
41 m = 1024 * 1024;
42 break;
43 }
44
45 if (*p)
46 {
47 fprintf (stderr, "%s: bad number (near %s)\n", str, p);
48 exit (1);
49 }
50
51 if (ULONG_MAX / m < n)
52 {
53 fprintf (stderr, "%s: number too big\n", str);
54 exit (1);
55 }
56 return m * n;
57}
58
59#ifdef DUMPSTATS
60static void
61dump_stats (GDBM_FILE dbf, size_t n)
62{
63 static size_t cache_size;
64 static struct gdbm_cache_stat *stat;
65 size_t access_count, cache_count;
66 FILE *fp;
67 char fname[80];
68 size_t i;
69
70 if (cache_size == 0)
71 {
72 if (gdbm_setopt (dbf, GDBM_GETCACHESIZE, &cache_size, sizeof(cache_size)))
73 {
74 fprintf (stderr, "GDBM_GETCACHESIZE: %s\n",
75 gdbm_strerror (gdbm_errno));
76 exit (1);
77 }
78 stat = calloc (cache_size, sizeof (stat[0]));
79 assert (stat != NULL);
80 }
81
82 gdbm_get_cache_stats (dbf, &access_count, &cache_count, stat, cache_size);
83
84 snprintf (fname, sizeof (fname), "%zu.stat", n);
85
86 fp = fopen (fname, "w");
87 assert (fp != NULL);
88
89 fprintf (fp, "%zu\n", access_count);
90 fprintf (fp, "%zu\n", cache_count);
91 for (i = 0; i < cache_count; i++)
92 {
93 fprintf (fp, "%zu %zu\n", stat[i].adr, stat[i].hits);
94 }
95 fclose (fp);
96
97 fprintf (stderr, "%80.80s\rDump file %s\n", "", fname);
98}
99
100static volatile int statsig;
101
102void
103sighan (int sig)
104{
105 statsig = 1;
106 signal (sig, sighan);
107}
108#endif
109
110char *dbname = "a.gdbm";
111char *kfname = "keys.txt";
112int percent;
113int verbose = 0;
114int time_verbose = 1;
115
116char *keybuf;
117char *keyptr;
118char *keyend;
119size_t nkeys;
120
121char *
122nextkey (void)
123{
124 char *ret = keyptr;
125
126 if (keyptr >= keyend)
127 return NULL;
128 keyptr += strlen (keyptr) + 1;
129 return ret;
130}
131
132void
133readkeys (char const *name)
134{
135 FILE *fp;
136 size_t n;
137 struct stat st;
138 char *p;
139
140 if (stat (name, &st))
141 {
142 fprintf (stderr, "%s: can't stat: %s\n", name, strerror (errno));
143 exit (1);
144 }
145
146 fp = fopen (name, "r");
147 if (!fp)
148 {
149 fprintf (stderr, "%s: can't read: %s\n", name, strerror (errno));
150 exit (1);
151 }
152
153 keybuf = malloc (st.st_size + 1);
154 assert (keybuf != NULL);
155 keyend = keybuf + st.st_size;
156 *keyend = 0;
157
158 if (fread (keybuf, st.st_size, 1, fp) != 1)
159 {
160 fprintf (stderr, "%s: read error: %s\n", name, strerror (errno));
161 exit (1);
162 }
163 fclose (fp);
164 keyptr = keybuf;
165
166 nkeys = 0;
167 for (p = keybuf; p < keyend; p++)
168 if (*p == '\n')
169 {
170 *p = 0;
171 nkeys++;
172 }
173}
174
175int
176main (int argc, char **argv)
177{
178 GDBM_FILE dbf;
179 datum key;
180 datum data;
181 int status = 0;
182 int i;
183 int print = 0;
184 unsigned long maxsize = 0;
185 int flags = 0;
186 struct timeval t_start, t_open, t_now, td;
187 char *keystr;
188
189 while ((i = getopt (argc, argv, "c:t:nTpv")) != EOF)
190 {
191 switch (i)
192 {
193 case 'n':
194 flags |= GDBM_NOMMAP;
195 break;
196
197 case 'p':
198 print = 1;
199 break;
200
201 case 'c':
202 maxsize = get_size (optarg);
203 break;
204
205 case 'T':
206 time_verbose = 0;
207 break;
208
209 case 'v':
210 verbose = 1;
211 break;
212
213 default:
214 exit (1);
215 }
216 }
217
218 argc -= optind;
219 argv += optind;
220
221 switch (argc)
222 {
223 case 2:
224 kfname = argv[1];
225 case 1:
226 dbname = argv[0];
227 break;
228 case 0:
229 break;
230 default:
231 fprintf (stderr, "too many arguments\n");
232 exit (1);
233 }
234
235 if (verbose)
236 printf ("PID %u\n", getpid ());
237
238#ifdef DUMPSTATS
239 signal (SIGUSR1, sighan);
240#endif
241
242 gettimeofday (&t_start, NULL);
243 dbf = gdbm_open (dbname, 0, GDBM_READER | flags, 00664, NULL);