]> mj.ucw.cz Git - libucw.git/blob - lib/db-test.c
Make it compile in GDBM mode.
[libucw.git] / lib / db-test.c
1 /*
2  *      Sherlock Library -- Database Manager -- Tests and Benchmarks
3  *
4  *      (c) 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
5  */
6
7 #if 1
8 #include "db.c"
9 #define NAME "SDBM"
10 #else
11 #include "db-emul.c"
12 #define NAME "GDBM"
13 #endif
14
15 #include <getopt.h>
16 #include <unistd.h>
17 #include <stdarg.h>
18 #include <sys/stat.h>
19
20 static struct sdbm_options opts = {
21   flags: SDBM_CREAT | SDBM_WRITE,
22   name: "db.test",
23   page_order: 10,
24   cache_size: 1024,
25   key_size: -1,
26   val_size: -1
27 };
28
29 static struct sdbm *d;
30 static int key_min, key_max;            /* min<0 -> URL distribution */
31 static int val_min, val_max;
32 static int num_keys;                    /* Number of distinct keys */
33 static int verbose;
34
35 static void
36 help(void)
37 {
38   printf("Usage: dbtest [<options>] <commands>\n\
39 \n\
40 Options:\n\
41 -c<n>           Use cache of <n> pages\n\
42 -p<n>           Use pages of order <n>\n\
43 -k<n>           Use key size <n>\n\
44 -k<m>-<n>       Use key size uniformly distributed between <m> and <n>\n\
45 -kU             Use keys with URL distribution\n\
46 -n<n>           Number of distinct keys\n\
47 -d<m>[-<n>]     Use specified value size (see -k<m>-<n>)\n\
48 -v              Be verbose\n\
49 -s              Turn on synchronous mode\n\
50 -S              Turn on supersynchronous mode\n\
51 -F              Turn on fast mode\n\
52 \n\
53 Commands:\n\
54 c               Fill database\n\
55 r               Rewrite database\n\
56 f[<p>%%][<n>]   Find <n> records with probability of success <p>%% (default=100)\n\
57 F[<p>%%][<n>]   Find, but don't fetch values\n\
58 d               Delete records\n\
59 w               Walk database\n\
60 W               Walk, but don't fetch values\n\
61 ");
62   exit(0);
63 }
64
65 static uns
66 krand(uns kn)
67 {
68   return kn * 2000000011;
69 }
70
71 static uns
72 gen_url_size(uns rnd)
73 {
74   uns l, m, r;
75   static uns utable[] = {
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 22, 108, 245, 481, 979, 3992, 7648, 13110, 19946, 27256, 34993, 43222, 52859, 64563,
77 80626, 117521, 147685, 188364, 233174, 290177, 347132, 407231, 465787, 540931, 628601, 710246, 808671, 922737, 1025691, 1138303,
78 1238802, 1344390, 1443843, 1533207, 1636494, 1739082, 1826911, 1910725, 1993940, 2094365, 2188987, 2267827, 2350190, 2441980,
79 2520713, 2593654, 2668632, 2736009, 2808356, 2889682, 2959300, 3017945, 3086488, 3146032, 3204818, 3251897, 3307001, 3349388,
80 3392798, 3433429, 3476765, 3529107, 3556884, 3585120, 3633005, 3677697, 3699561, 3716660, 3739823, 3765154, 3795096, 3821184,
81 3858117, 3908757, 3929095, 3943264, 3957033, 3969588, 3983441, 3994630, 4005413, 4028890, 4039678, 4058007, 4071906, 4087029,
82 4094233, 4105259, 4111603, 4120338, 4127364, 4133983, 4140310, 4144843, 4150565, 4155974, 4165132, 4170648, 4176811, 4187118,
83 4190866, 4199051, 4206686, 4216122, 4226109, 4233721, 4254123, 4261792, 4270396, 4276650, 4282932, 4291738, 4295932, 4299370,
84 4304011, 4307098, 4311866, 4318168, 4325730, 4329774, 4332946, 4336305, 4339770, 4345237, 4349038, 4356129, 4362872, 4366542,
85 4371077, 4374524, 4376733, 4378794, 4380652, 4382340, 4383552, 4385952, 4386914, 4393123, 4394106, 4395142, 4396593, 4399112,
86 4399909, 4401015, 4401780, 4402616, 4403454, 4404481, 4405231, 4405947, 4406886, 4408364, 4409159, 4409982, 4410872, 4412010,
87 4413341, 4414161, 4415673, 4417135, 4418032, 4419117, 4419952, 4420677, 4421387, 4421940, 4422469, 4423210, 4423696, 4424274,
88 4424982, 4425665, 4426363, 4427018, 4427969, 4428992, 4429791, 4430804, 4432601, 4433440, 4434157, 4434967, 4436280, 4439784,
89 4444255, 4445544, 4446416, 4447620, 4449638, 4453004, 4455470, 4456982, 4457956, 4458617, 4459538, 4460007, 4460377, 4460768,
90 4461291, 4461520, 4461678, 4461911, 4462063, 4462239, 4462405, 4462607, 4462666, 4462801, 4462919, 4463108, 4463230, 4463438,
91 4463530, 4463698, 4463779, 4463908, 4463991, 4464138, 4464188, 4464391, 4464580, 4464868, 4464980, 4465174, 4465255, 4465473,
92 4465529, 4465681, 4465746, 4465916, 4465983, 4466171, 4466248, 4466430, 4466560, 4466751, 4466930, 4467807, 4468847, 4469940,
93 4470344, 4470662, 4470716, 4471120, 4471389, 4471814, 4472141, 4472545, 4472687, 4473051, 4473253, 4473603, 4473757, 4474065,
94 4474125, 4474354, 4474428, 4474655, 4474705, 4474841, 4474858, 4475133, 4475201, 4475327, 4475367, 4475482, 4475533, 4475576,
95 4475586, 4475616, 4475637, 4475659, 4475696, 4475736, 4475775, 4475794, 4476156, 4476711, 4477004, 4477133, 4477189, 4477676,
96 4477831, 4477900, 4477973, 4477994, 4478011, 4478040, 4478063, 4478085, 4478468, 4478715, 4479515, 4480034, 4481804, 4483259,
97 4483866, 4484202, 4484932, 4485693, 4486184, 4486549, 4486869, 4487405, 4487639, 4487845, 4488086, 4488256, 4488505, 4488714,
98 4492669, 4496233, 4497738, 4498122, 4498653, 4499862, 4501169, 4501627, 4501673, 4501811, 4502182, 4502475, 4502533, 4502542,
99 4502548, 4502733, 4503389, 4504381, 4505070, 4505378, 4505814, 4506031, 4506336, 4506642, 4506845, 4506971, 4506986, 4507016,
100 4507051, 4507098, 4507107, 4507114, 4507139, 4507478, 4507643, 4507674, 4507694, 4507814, 4507894, 4507904, 4507929, 4507989,
101 4508023, 4508047, 4508053, 4508063, 4508075, 4508092, 4508104, 4508113, 4508239, 4508285, 4508324, 4508335, 4508340, 4508378,
102 4508405, 4508419, 4508436, 4508449, 4508470, 4508488, 4508515, 4508541, 4508564, 4508570, 4508584, 4508594, 4508607, 4508634,
103 4508652, 4508665, 4508673, 4508692, 4508704, 4508742, 4508755, 4508773, 4508788, 4508798, 4508832, 4508869, 4508885, 4508905,
104 4508915, 4508947, 4508956, 4509061, 4509070, 4509357, 4509368, 4509380, 4509393, 4509401, 4509412, 4509426, 4509438, 4509451,
105 4509461, 4509473, 4509489, 4509498, 4509512, 4509537, 4509568, 4509582, 4509621, 4509629, 4509747, 4509766, 4509776, 4509795,
106 4509802, 4509813, 4509822, 4509829, 4509834, 4509844, 4509854, 4509863, 4509868, 4509875, 4509886, 4509898, 4509908, 4509920,
107 4509932, 4509941, 4509949, 4509955, 4509967, 4509972, 4509979, 4509987, 4509999, 4510002, 4510010, 4510014, 4510018, 4510025,
108 4510028, 4510049, 4510055, 4510061, 4510068, 4510079, 4510085, 4510091, 4510098, 4510102, 4510104, 4510110, 4510121, 4510128,
109 4510132, 4510138, 4510144, 4510145, 4510153, 4510161, 4510174, 4510196, 4510199, 4510208, 4510209, 4510212, 4510216, 4510217,
110 4510219, 4510222, 4510228, 4510231, 4510236, 4510241, 4510245, 4510248, 4510250, 4510254, 4510255, 4510261, 4510262, 4510266,
111 4510266, 4510271, 4510285, 4510287, 4510291, 4510295, 4510303, 4510306, 4510308, 4510310, 4510314, 4510319, 4510320, 4510324,
112 4510328, 4510333, 4510333, 4510336, 4510340, 4510342, 4510348, 4510353, 4510359, 4510362, 4510365, 4510371, 4510373, 4510375,
113 4510378, 4510380, 4510385, 4510389, 4510391, 4510391, 4510394, 4510396, 4510397, 4510398, 4510400, 4510403, 4510406, 4510407,
114 4510408, 4510409, 4510411, 4510413, 4510417, 4510417, 4510419, 4510422, 4510426, 4510427, 4510430, 4510435, 4510437, 4510439,
115 4510440, 4510442, 4510442, 4510446, 4510447, 4510448, 4510450, 4510451, 4510451, 4510453, 4510454, 4510455, 4510457, 4510460,
116 4510460, 4510460, 4510462, 4510463, 4510466, 4510468, 4510472, 4510475, 4510480, 4510482, 4510483, 4510486, 4510488, 4510492,
117 4510494, 4510497, 4510497, 4510499, 4510503, 4510505, 4510506, 4510507, 4510509, 4510512, 4510514, 4510527, 4510551, 4510553,
118 4510554, 4510555, 4510556, 4510558, 4510561, 4510562, 4510566, 4510567, 4510568, 4510570, 4510573, 4510574, 4510586, 4510603,
119 4510605, 4510607, 4510610, 4510610, 4510613, 4510613, 4510614, 4510614, 4510615, 4510616, 4510616, 4510620, 4510622, 4510623,
120 4510624, 4510627, 4510628, 4510630, 4510631, 4510632, 4510634, 4510634, 4510634, 4510636, 4510636, 4510639, 4510639, 4510640,
121 4510643, 4510647, 4510649, 4510650, 4510653, 4510653, 4510653, 4510653, 4510656, 4510659, 4510661, 4510664, 4510665, 4510669,
122 4510672, 4510673, 4510674, 4510675, 4510680, 4510683, 4510684, 4510686, 4510687, 4510690, 4510691, 4510693, 4510693, 4510697,
123 4510699, 4510700, 4510703, 4510704, 4510709, 4510711, 4510713, 4510713, 4510720, 4510720, 4510722, 4510724, 4510727, 4510729,
124 4510735, 4510735, 4510738, 4510740, 4510744, 4510745, 4510746, 4510748, 4510754, 4510756, 4510758, 4510761, 4510764, 4510766,
125 4510768, 4510768, 4510770, 4510770, 4510772, 4510774, 4510775, 4510775, 4510775, 4510776, 4510777, 4510780, 4510782, 4510783,
126 4510785, 4510786, 4510788, 4510789, 4510791, 4510793, 4510793, 4510793, 4510795, 4510795, 4510799, 4510803, 4510804, 4510804,
127 4510804, 4510805, 4510807, 4510809, 4510811, 4510811, 4510813, 4510815, 4510815, 4510816, 4510819, 4510820, 4510824, 4510827,
128 4510829, 4510829, 4510830, 4510833, 4510835, 4510837, 4510838, 4510838, 4510839, 4510840, 4510840, 4510842, 4510842, 4510843,
129 4510845, 4510845, 4510845, 4510847, 4510848, 4510848, 4510848, 4510850, 4510853, 4510855, 4510857, 4510859, 4510861, 4510862,
130 4510864, 4510865, 4510865, 4510865, 4510869, 4510869, 4510869, 4510869, 4510869, 4510870, 4510870, 4510872, 4510872, 4510873,
131 4510874, 4510875, 4510875, 4510877, 4510879, 4510879, 4510879, 4510879, 4510880, 4510881, 4510882, 4510883, 4510884, 4510885,
132 4510886, 4510887, 4510890, 4510890, 4510891, 4510892, 4510892, 4510893, 4510893, 4510895, 4510895, 4510896, 4510897, 4510899,
133 4510901, 4510901, 4510901, 4510902, 4510903, 4510903, 4510903, 4510905, 4510905, 4510906, 4510906, 4510907, 4510907, 4510909,
134 4510910, 4510911, 4510911, 4510911, 4510913, 4510913, 4510914, 4510914, 4510914, 4510915, 4510916, 4510918, 4510918, 4510919,
135 4510919, 4510919, 4510920, 4510921, 4510922, 4510923, 4510924, 4510924, 4510924, 4510924, 4510926, 4510927, 4510928, 4510928,
136 4510928, 4510928, 4510928, 4510930, 4510933, 4510935, 4510935, 4510935, 4510935, 4510935, 4510936, 4510938, 4510947, 4510966,
137 4510967, 4510969, 4510973, 4510973, 4510974, 4510974, 4510974, 4510974, 4510974, 4510974, 4510975, 4510976, 4510976, 4510976,
138 4510976, 4510976, 4510976, 4510976, 4510977, 4510979, 4510979, 4510979, 4510979, 4510979, 4510979, 4510980, 4510980, 4510980,
139 4510980, 4510981, 4510981, 4510981, 4510982, 4510982, 4510982, 4510982, 4510982, 4510982, 4510982, 4510983, 4510983, 4510984,
140 4510984, 4510984, 4510984, 4510984, 4510985, 4510985, 4510985, 4510985, 4510987, 4510987, 4510987, 4510988, 4510988, 4510989,
141 4510989, 4510989, 4510989, 4510989, 4510990, 4510990, 4510990, 4510990, 4510990, 4510990, 4510990, 4510991, 4510991, 4510991,
142 4510991, 4510991, 4510991, 4510991, 4510992, 4510992, 4510992, 4510992, 4510992, 4510992, 4510992, 4510993, 4510993, 4510993,
143 4510994, 4510994, 4510994, 4510994, 4510995, 4510995, 4510996, 4510997, 4510998, 4510999, 4510999, 4511000, 4511000, 4511001,
144 4511001, 4511002, 4511002, 4511002, 4511003, 4511004, 4511004, 4511004, 4511004, 4511005, 4511006, 4511008, 4511008, 4511008,
145 4511009, 4511009, 4511009, 4511009, 4511010, 4511011, 4511011, 4511012, 4511012, 4511012, 4511012, 4511013, 4511013, 4511014,
146 4511014, 4511014, 4511014, 4511015, 4511018, 4511018, 4511018, 4511018, 4511018, 4511018, 4511018, 4511020, 4511020, 4511020,
147 4511020, 4511020, 4511020, 4511020, 4511021, 4511021, 4511021, 4511021, 4511021, 4511021, 4511021, 4511021, 4511021, 4511021,
148 4511021
149   };
150
151   rnd %= utable[1024];
152   l = 0; r = 1023;
153   while (l < r)
154     {
155       m = (l+r)/2;
156       if (utable[m] == rnd)
157         return m;
158       if (utable[m] >= rnd)
159         r = m - 1;
160       else
161         l = m + 1;
162     }
163   return l;
164 }
165
166 static uns
167 gen_size(uns min, uns max, uns rnd)
168 {
169   if (min == max)
170     return min;
171   else
172     return min + rnd % (max - min + 1);
173 }
174
175 static void
176 gen_random(byte *buf, uns size, uns kn)
177 {
178   kn = (kn + 0x36221057) ^ (kn << 24) ^ (kn << 15);
179   while (size--)
180     {
181       *buf++ = kn >> 24;
182       kn = kn*257 + 17;
183     }
184 }
185
186 static int
187 keygen(byte *buf, uns kn)
188 {
189   uns size, rnd;
190
191   rnd = krand(kn);
192   if (key_min < 0)
193     size = gen_url_size(rnd);
194   else
195     size = gen_size(key_min, key_max, rnd);
196   *buf++ = kn >> 24;
197   *buf++ = kn >> 16;
198   *buf++ = kn >> 8;
199   *buf++ = kn;
200   if (size < 4)
201     return 4;
202   gen_random(buf, size-4, kn);
203   return size;
204 }
205
206 static int
207 valgen(byte *buf, uns kn)
208 {
209   uns size = gen_size(val_min, val_max, krand(kn));
210   gen_random(buf, size, kn);
211   return size;
212 }
213
214 static uns
215 keydec(byte *buf)
216 {
217   return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
218 }
219
220 static void
221 verb(char *msg, ...)
222 {
223   int cat = 1;
224   va_list args;
225
226   va_start(args, msg);
227   if (msg[0] == '^' && msg[1])
228     {
229       cat = msg[1] - '0';
230       msg += 2;
231     }
232   if (verbose >= cat)
233     vfprintf(stderr, msg, args);
234   va_end(args);
235 }
236
237 static void
238 parse_size(int *min, int *max, char *c)
239 {
240   char *d;
241
242   if ((d = strchr(c, '-')))
243     {
244       *d++ = 0;
245       *min = atol(c);
246       *max = atol(d);
247     }
248   else
249     *min = *max = atol(c);
250 }
251
252 int main(int argc, char **argv)
253 {
254   int c, i, j, k, l, m;
255   byte kb[2048], vb[2048], vb2[2048];
256   uns ks, vs, vs2, perc, cnt;
257   char *ch;
258
259   initlog("dbtest");
260   setvbuf(stdout, NULL, _IONBF, 0);
261   setvbuf(stderr, NULL, _IONBF, 0);
262   while ((c = getopt(argc, argv, "c:p:k:n:d:vsSF")) >= 0)
263     switch (c)
264       {
265       case 'c':
266         opts.cache_size = atol(optarg);
267         break;
268       case 'p':
269         opts.page_order = atol(optarg);
270         break;
271       case 'k':
272         if (!strcmp(optarg, "U"))
273           key_min = key_max = -1;
274         else
275           parse_size(&key_min, &key_max, optarg);
276         break;
277       case 'n':
278         num_keys = atol(optarg);
279         break;
280       case 'd':
281         parse_size(&val_min, &val_max, optarg);
282         break;
283       case 'v':
284         verbose++;
285         break;
286       case 's':
287         opts.flags |= SDBM_SYNC;
288         break;
289       case 'S':
290         opts.flags |= SDBM_SYNC | SDBM_FSYNC;
291         break;
292       case 'F':
293         opts.flags |= SDBM_FAST;
294         break;
295       default:
296         help();
297       }
298
299   if (key_min >= 0 && key_min < 4)
300     key_min = key_max = 4;
301   if (key_min == key_max && key_min >= 0)
302     opts.key_size = key_min;
303   if (val_min == val_max)
304     opts.val_size = val_min;
305   if (!num_keys)
306     die("Number of keys not given");
307
308   printf(NAME " benchmark: %d records, keys ", num_keys);
309   if (key_min < 0)
310     printf("<URL>");
311   else
312     printf("%d-%d", key_min, key_max);
313   printf(", values %d-%d, page size %d, cache %d pages\n", val_min, val_max, 1 << opts.page_order, opts.cache_size);
314
315   verb("OPEN(%s, key=%d, val=%d, cache=%d, pgorder=%d)\n", opts.name, opts.key_size, opts.val_size,
316        opts.cache_size, opts.page_order);
317   unlink(opts.name);
318   d = sdbm_open(&opts);
319   if (!d)
320     die("open failed: %m");
321
322   while (optind < argc)
323     {
324       char *o = argv[optind++];
325       init_timer();
326       switch (*o)
327         {
328         case 'c':
329           printf("create %d: ", num_keys);
330           for(i=0; i<num_keys; i++)
331             {
332               verb("^2%d\r", i);
333               ks = keygen(kb, i);
334               vs = valgen(vb, i);
335               if (sdbm_store(d, kb, ks, vb, vs) != 1) die("store failed");
336             }
337           break;
338         case 'r':
339           printf("rewrite %d: ", num_keys);
340           for(i=0; i<num_keys; i++)
341             {
342               verb("^2%d\r", i);
343               ks = keygen(kb, i);
344               vs = valgen(vb, i);
345               if (sdbm_replace(d, kb, ks, vb, vs) != 1) die("replace failed");
346             }
347           break;
348         case 'f':
349         case 'F':
350           c = (*o++ == 'f');
351           if ((ch = strchr(o, '%')))
352             {
353               *ch++ = 0;
354               perc = atol(o);
355             }
356           else
357             {
358               ch = o;
359               perc = 100;
360             }
361           cnt = atol(o);
362           if (!cnt)
363             {
364               cnt = num_keys;
365               m = (perc == 100);
366             }
367           else
368             m = 0;
369           printf("%s fetch %d (%d%% success, with%s values): ", (m ? "sequential" : "random"), cnt, perc, (c ? "" : "out"));
370           i = -1;
371           while (cnt--)
372             {
373               if (m)
374                 i++;
375               else
376                 i = random_max(num_keys) + ((random_max(100) < perc) ? 0 : num_keys);
377               verb("^2%d\r", i);
378               ks = keygen(kb, i);
379               if (c)
380                 {
381                   vs2 = sizeof(vb2);
382                   j = sdbm_fetch(d, kb, ks, vb2, &vs2);
383                 }
384               else
385                 j = sdbm_fetch(d, kb, ks, NULL, NULL);
386               if (j < 0)
387                 die("fetch: error %d", j);
388               if ((i < num_keys) != j)
389                 die("fetch mismatch at key %d, res %d", i, j);
390               if (c && j)
391                 {
392                   vs = valgen(vb, i);
393                   if (vs != vs2 || memcmp(vb, vb2, vs))
394                     die("fetch data mismatch at key %d: %d,%d", i, vs, vs2);
395                 }
396             }
397           break;
398         case 'd':
399           printf("delete %d: ", num_keys);
400           for(i=0; i<num_keys; i++)
401             {
402               verb("^2%d\r", i);
403               ks = keygen(kb, i);
404               if (sdbm_delete(d, kb, ks) != 1) die("delete failed");
405             }
406           break;
407         case 'w':
408         case 'W':
409           c = (*o == 'w');
410           i = k = l = m = 0;
411           printf("walk %d (with%s keys): ", num_keys, (c ? "" : "out"));
412           sdbm_rewind(d);
413           for(;;)
414             {
415               ks = sizeof(kb);
416               vs = sizeof(vb);
417               if (c)
418                 j = sdbm_get_next(d, kb, &ks, vb, &vs);
419               else
420                 j = sdbm_get_next(d, kb, &ks, NULL, NULL);
421               if (!j)
422                 break;
423               if (ks < 4)
424                 die("get_next: too short");
425               i = keydec(kb);
426               if (i < 0 || i >= num_keys)
427                 die("get_next: %d out of range", i);
428               verb("^2%d\r", i);
429               vs2 = keygen(vb2, i);
430               if (ks != vs2 || memcmp(kb, vb2, ks))
431                 die("get_next: key mismatch at %d", i);
432               if (c)
433                 {
434                   vs2 = valgen(vb2, i);
435                   if (vs != vs2 || memcmp(vb, vb2, vs))
436                     die("get_next: data mismatch at %d", i);
437                 }
438               l += k;
439               m += i;
440               k++;
441             }
442           if (k != num_keys)
443             die("fetch: wrong # of keys: %d != %d", k, num_keys);
444           if (l != m)
445             die("fetch: wrong checksum: %d != %d", l, m);
446           break;
447         default:
448           help();
449         }
450       sdbm_sync(d);
451       printf("%d ms\n", get_timer());
452     }
453
454   verb("CLOSE\n");
455   sdbm_close(d);
456
457   {
458     struct stat st;
459     if (stat(opts.name, &st)) die("stat: %m");
460     printf("file size: %d bytes\n", (int) st.st_size);
461   }
462   return 0;
463 }