]> mj.ucw.cz Git - libucw.git/blob - lib/db-test.c
Stupid bug.
[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 #define PROGRESS(i) if ((verbose > 2) || (verbose > 1 && !(i & 1023))) fprintf(stderr, "%d\r", i)
253
254 int main(int argc, char **argv)
255 {
256   int c, i, j, k, l, m;
257   byte kb[2048], vb[2048], vb2[2048];
258   uns ks, vs, vs2, perc, cnt;
259   char *ch;
260
261   initlog("dbtest");
262   setvbuf(stdout, NULL, _IONBF, 0);
263   setvbuf(stderr, NULL, _IONBF, 0);
264   while ((c = getopt(argc, argv, "c:p:k:n:d:vsSF")) >= 0)
265     switch (c)
266       {
267       case 'c':
268         opts.cache_size = atol(optarg);
269         break;
270       case 'p':
271         opts.page_order = atol(optarg);
272         break;
273       case 'k':
274         if (!strcmp(optarg, "U"))
275           key_min = key_max = -1;
276         else
277           parse_size(&key_min, &key_max, optarg);
278         break;
279       case 'n':
280         num_keys = atol(optarg);
281         break;
282       case 'd':
283         parse_size(&val_min, &val_max, optarg);
284         break;
285       case 'v':
286         verbose++;
287         break;
288       case 's':
289         opts.flags |= SDBM_SYNC;
290         break;
291       case 'S':
292         opts.flags |= SDBM_SYNC | SDBM_FSYNC;
293         break;
294       case 'F':
295         opts.flags |= SDBM_FAST;
296         break;
297       default:
298         help();
299       }
300
301   if (key_min >= 0 && key_min < 4)
302     key_min = key_max = 4;
303   if (key_min == key_max && key_min >= 0)
304     opts.key_size = key_min;
305   if (val_min == val_max)
306     opts.val_size = val_min;
307   if (!num_keys)
308     die("Number of keys not given");
309
310   printf(NAME " benchmark: %d records, keys ", num_keys);
311   if (key_min < 0)
312     printf("<URL>");
313   else
314     printf("%d-%d", key_min, key_max);
315   printf(", values %d-%d, page size %d, cache %d pages\n", val_min, val_max, 1 << opts.page_order, opts.cache_size);
316
317   verb("OPEN(%s, key=%d, val=%d, cache=%d, pgorder=%d)\n", opts.name, opts.key_size, opts.val_size,
318        opts.cache_size, opts.page_order);
319   unlink(opts.name);
320   d = sdbm_open(&opts);
321   if (!d)
322     die("open failed: %m");
323
324   while (optind < argc)
325     {
326       char *o = argv[optind++];
327       init_timer();
328       switch (*o)
329         {
330         case 'c':
331           printf("create %d: ", num_keys);
332           for(i=0; i<num_keys; i++)
333             {
334               PROGRESS(i);
335               ks = keygen(kb, i);
336               vs = valgen(vb, i);
337               if (sdbm_store(d, kb, ks, vb, vs) != 1) die("store failed");
338             }
339           break;
340         case 'r':
341           printf("rewrite %d: ", num_keys);
342           for(i=0; i<num_keys; i++)
343             {
344               PROGRESS(i);
345               ks = keygen(kb, i);
346               vs = valgen(vb, i);
347               if (sdbm_replace(d, kb, ks, vb, vs) != 1) die("replace failed");
348             }
349           break;
350         case 'f':
351         case 'F':
352           c = (*o++ == 'f');
353           if ((ch = strchr(o, '%')))
354             {
355               *ch++ = 0;
356               perc = atol(o);
357             }
358           else
359             {
360               ch = o;
361               perc = 100;
362             }
363           cnt = atol(ch);
364           if (!cnt)
365             {
366               cnt = num_keys;
367               m = (perc == 100);
368             }
369           else
370             m = 0;
371           printf("%s fetch %d (%d%% success, with%s values): ", (m ? "sequential" : "random"), cnt, perc, (c ? "" : "out"));
372           i = -1;
373           while (cnt--)
374             {
375               if (m)
376                 i++;
377               else
378                 i = random_max(num_keys) + ((random_max(100) < perc) ? 0 : num_keys);
379               PROGRESS(i);
380               ks = keygen(kb, i);
381               if (c)
382                 {
383                   vs2 = sizeof(vb2);
384                   j = sdbm_fetch(d, kb, ks, vb2, &vs2);
385                 }
386               else
387                 j = sdbm_fetch(d, kb, ks, NULL, NULL);
388               if (j < 0)
389                 die("fetch: error %d", j);
390               if ((i < num_keys) != j)
391                 die("fetch mismatch at key %d, res %d", i, j);
392               if (c && j)
393                 {
394                   vs = valgen(vb, i);
395                   if (vs != vs2 || memcmp(vb, vb2, vs))
396                     die("fetch data mismatch at key %d: %d,%d", i, vs, vs2);
397                 }
398             }
399           break;
400         case 'd':
401           printf("delete %d: ", num_keys);
402           for(i=0; i<num_keys; i++)
403             {
404               PROGRESS(i);
405               ks = keygen(kb, i);
406               if (sdbm_delete(d, kb, ks) != 1) die("delete failed");
407             }
408           break;
409         case 'w':
410         case 'W':
411           c = (*o == 'w');
412           i = k = l = m = 0;
413           printf("walk %d (with%s keys): ", num_keys, (c ? "" : "out"));
414           sdbm_rewind(d);
415           for(;;)
416             {
417               ks = sizeof(kb);
418               vs = sizeof(vb);
419               if (c)
420                 j = sdbm_get_next(d, kb, &ks, vb, &vs);
421               else
422                 j = sdbm_get_next(d, kb, &ks, NULL, NULL);
423               if (!j)
424                 break;
425               if (ks < 4)
426                 die("get_next: too short");
427               i = keydec(kb);
428               if (i < 0 || i >= num_keys)
429                 die("get_next: %d out of range", i);
430               PROGRESS(i);
431               vs2 = keygen(vb2, i);
432               if (ks != vs2 || memcmp(kb, vb2, ks))
433                 die("get_next: key mismatch at %d", i);
434               if (c)
435                 {
436                   vs2 = valgen(vb2, i);
437                   if (vs != vs2 || memcmp(vb, vb2, vs))
438                     die("get_next: data mismatch at %d", i);
439                 }
440               l += k;
441               m += i;
442               k++;
443             }
444           if (k != num_keys)
445             die("fetch: wrong # of keys: %d != %d", k, num_keys);
446           if (l != m)
447             die("fetch: wrong checksum: %d != %d", l, m);
448           break;
449         default:
450           help();
451         }
452       sdbm_sync(d);
453       printf("%d ms\n", get_timer());
454     }
455
456   verb("CLOSE\n");
457   sdbm_close(d);
458
459   {
460     struct stat st;
461     if (stat(opts.name, &st)) die("stat: %m");
462     printf("file size: %d bytes\n", (int) st.st_size);
463   }
464   return 0;
465 }