]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tokyocabinet/tcatest.c
ebl Add tokyocabinet source to bacula
[bacula/bacula] / bacula / src / lib / tokyocabinet / tcatest.c
1 /*************************************************************************************************
2  * The test cases of the abstract database API
3  *                                                      Copyright (C) 2006-2008 Mikio Hirabayashi
4  * This file is part of Tokyo Cabinet.
5  * Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of
6  * the GNU Lesser General Public License as published by the Free Software Foundation; either
7  * version 2.1 of the License or any later version.  Tokyo Cabinet is distributed in the hope
8  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
10  * License for more details.
11  * You should have received a copy of the GNU Lesser General Public License along with Tokyo
12  * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13  * Boston, MA 02111-1307 USA.
14  *************************************************************************************************/
15
16
17 #include <tcutil.h>
18 #include <tcadb.h>
19 #include "myconf.h"
20
21 #define RECBUFSIZ      32                // buffer for records
22
23
24 /* global variables */
25 const char *g_progname;                  // program name
26
27
28 /* function prototypes */
29 int main(int argc, char **argv);
30 static void usage(void);
31 static void iprintf(const char *format, ...);
32 static void eprint(TCADB *adb, const char *func);
33 static int myrand(int range);
34 static int runwrite(int argc, char **argv);
35 static int runread(int argc, char **argv);
36 static int runremove(int argc, char **argv);
37 static int runrcat(int argc, char **argv);
38 static int runmisc(int argc, char **argv);
39 static int runwicked(int argc, char **argv);
40 static int procwrite(const char *name, int rnum);
41 static int procread(const char *name);
42 static int procremove(const char *name);
43 static int procrcat(const char *name, int rnum);
44 static int procmisc(const char *name, int rnum);
45 static int procwicked(const char *name, int rnum);
46
47
48 /* main routine */
49 int main(int argc, char **argv){
50   g_progname = argv[0];
51   srand((unsigned int)(tctime() * 1000) % UINT_MAX);
52   if(argc < 2) usage();
53   int rv = 0;
54   if(!strcmp(argv[1], "write")){
55     rv = runwrite(argc, argv);
56   } else if(!strcmp(argv[1], "read")){
57     rv = runread(argc, argv);
58   } else if(!strcmp(argv[1], "remove")){
59     rv = runremove(argc, argv);
60   } else if(!strcmp(argv[1], "rcat")){
61     rv = runrcat(argc, argv);
62   } else if(!strcmp(argv[1], "misc")){
63     rv = runmisc(argc, argv);
64   } else if(!strcmp(argv[1], "wicked")){
65     rv = runwicked(argc, argv);
66   } else {
67     usage();
68   }
69   return rv;
70 }
71
72
73 /* print the usage and exit */
74 static void usage(void){
75   fprintf(stderr, "%s: test cases of the abstract database API of Tokyo Cabinet\n", g_progname);
76   fprintf(stderr, "\n");
77   fprintf(stderr, "usage:\n");
78   fprintf(stderr, "  %s write name rnum\n", g_progname);
79   fprintf(stderr, "  %s read name\n", g_progname);
80   fprintf(stderr, "  %s remove name\n", g_progname);
81   fprintf(stderr, "  %s rcat name rnum\n", g_progname);
82   fprintf(stderr, "  %s misc name rnum\n", g_progname);
83   fprintf(stderr, "  %s wicked name rnum\n", g_progname);
84   fprintf(stderr, "\n");
85   exit(1);
86 }
87
88
89 /* print formatted information string and flush the buffer */
90 static void iprintf(const char *format, ...){
91   va_list ap;
92   va_start(ap, format);
93   vprintf(format, ap);
94   fflush(stdout);
95   va_end(ap);
96 }
97
98
99 /* print error message of abstract database */
100 static void eprint(TCADB *adb, const char *func){
101   fprintf(stderr, "%s: %s: error\n", g_progname, func);
102 }
103
104
105 /* get a random number */
106 static int myrand(int range){
107   return (int)((double)range * rand() / (RAND_MAX + 1.0));
108 }
109
110
111 /* parse arguments of write command */
112 static int runwrite(int argc, char **argv){
113   char *name = NULL;
114   char *rstr = NULL;
115   for(int i = 2; i < argc; i++){
116     if(!name && argv[i][0] == '-'){
117       usage();
118     } else if(!name){
119       name = argv[i];
120     } else if(!rstr){
121       rstr = argv[i];
122     } else {
123       usage();
124     }
125   }
126   if(!name || !rstr) usage();
127   int rnum = atoi(rstr);
128   if(rnum < 1) usage();
129   int rv = procwrite(name, rnum);
130   return rv;
131 }
132
133
134 /* parse arguments of read command */
135 static int runread(int argc, char **argv){
136   char *name = NULL;
137   for(int i = 2; i < argc; i++){
138     if(!name && argv[i][0] == '-'){
139       usage();
140     } else if(!name){
141       name = argv[i];
142     } else {
143       usage();
144     }
145   }
146   if(!name) usage();
147   int rv = procread(name);
148   return rv;
149 }
150
151
152 /* parse arguments of remove command */
153 static int runremove(int argc, char **argv){
154   char *name = NULL;
155   for(int i = 2; i < argc; i++){
156     if(!name && argv[i][0] == '-'){
157       usage();
158     } else if(!name){
159       name = argv[i];
160     } else {
161       usage();
162     }
163   }
164   if(!name) usage();
165   int rv = procremove(name);
166   return rv;
167 }
168
169
170 /* parse arguments of rcat command */
171 static int runrcat(int argc, char **argv){
172   char *name = NULL;
173   char *rstr = NULL;
174   for(int i = 2; i < argc; i++){
175     if(!name && argv[i][0] == '-'){
176       usage();
177     } else if(!name){
178       name = argv[i];
179     } else if(!rstr){
180       rstr = argv[i];
181     } else {
182       usage();
183     }
184   }
185   if(!name || !rstr) usage();
186   int rnum = atoi(rstr);
187   if(rnum < 1) usage();
188   int rv = procrcat(name, rnum);
189   return rv;
190 }
191
192
193 /* parse arguments of misc command */
194 static int runmisc(int argc, char **argv){
195   char *name = NULL;
196   char *rstr = NULL;
197   for(int i = 2; i < argc; i++){
198     if(!name && argv[i][0] == '-'){
199       usage();
200     } else if(!name){
201       name = argv[i];
202     } else if(!rstr){
203       rstr = argv[i];
204     } else {
205       usage();
206     }
207   }
208   if(!name || !rstr) usage();
209   int rnum = atoi(rstr);
210   if(rnum < 1) usage();
211   int rv = procmisc(name, rnum);
212   return rv;
213 }
214
215
216 /* parse arguments of wicked command */
217 static int runwicked(int argc, char **argv){
218   char *name = NULL;
219   char *rstr = NULL;
220   for(int i = 2; i < argc; i++){
221     if(!name && argv[i][0] == '-'){
222       usage();
223     } else if(!name){
224       name = argv[i];
225     } else if(!rstr){
226       rstr = argv[i];
227     } else {
228       usage();
229     }
230   }
231   if(!name || !rstr) usage();
232   int rnum = atoi(rstr);
233   if(rnum < 1) usage();
234   int rv = procwicked(name, rnum);
235   return rv;
236 }
237
238
239 /* perform write command */
240 static int procwrite(const char *name, int rnum){
241   iprintf("<Writing Test>\n  name=%s  rnum=%d\n\n", name, rnum);
242   bool err = false;
243   double stime = tctime();
244   TCADB *adb = tcadbnew();
245   if(!tcadbopen(adb, name)){
246     eprint(adb, "tcadbopen");
247     err = true;
248   }
249   for(int i = 1; i <= rnum; i++){
250     char buf[RECBUFSIZ];
251     int len = sprintf(buf, "%08d", i);
252     if(!tcadbput(adb, buf, len, buf, len)){
253       eprint(adb, "tcadbput");
254       err = true;
255       break;
256     }
257     if(rnum > 250 && i % (rnum / 250) == 0){
258       putchar('.');
259       fflush(stdout);
260       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
261     }
262   }
263   iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
264   iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
265   if(!tcadbclose(adb)){
266     eprint(adb, "tcadbclose");
267     err = true;
268   }
269   tcadbdel(adb);
270   iprintf("time: %.3f\n", tctime() - stime);
271   iprintf("%s\n\n", err ? "error" : "ok");
272   return err ? 1 : 0;
273 }
274
275
276 /* perform read command */
277 static int procread(const char *name){
278   iprintf("<Reading Test>\n  name=%s\n\n", name);
279   bool err = false;
280   double stime = tctime();
281   TCADB *adb = tcadbnew();
282   if(!tcadbopen(adb, name)){
283     eprint(adb, "tcadbopen");
284     err = true;
285   }
286   int rnum = tcadbrnum(adb);
287   for(int i = 1; i <= rnum; i++){
288     char kbuf[RECBUFSIZ];
289     int ksiz = sprintf(kbuf, "%08d", i);
290     int vsiz;
291     char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
292     if(!vbuf){
293       eprint(adb, "tcadbget");
294       err = true;
295       break;
296     }
297     free(vbuf);
298     if(rnum > 250 && i % (rnum / 250) == 0){
299       putchar('.');
300       fflush(stdout);
301       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
302     }
303   }
304   iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
305   iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
306   if(!tcadbclose(adb)){
307     eprint(adb, "tcadbclose");
308     err = true;
309   }
310   tcadbdel(adb);
311   iprintf("time: %.3f\n", tctime() - stime);
312   iprintf("%s\n\n", err ? "error" : "ok");
313   return err ? 1 : 0;
314 }
315
316
317 /* perform remove command */
318 static int procremove(const char *name){
319   iprintf("<Removing Test>\n  name=%s\n\n", name);
320   bool err = false;
321   double stime = tctime();
322   TCADB *adb = tcadbnew();
323   if(!tcadbopen(adb, name)){
324     eprint(adb, "tcadbopen");
325     err = true;
326   }
327   int rnum = tcadbrnum(adb);
328   for(int i = 1; i <= rnum; i++){
329     char kbuf[RECBUFSIZ];
330     int ksiz = sprintf(kbuf, "%08d", i);
331     if(!tcadbout(adb, kbuf, ksiz)){
332       eprint(adb, "tcadbout");
333       err = true;
334       break;
335     }
336     if(rnum > 250 && i % (rnum / 250) == 0){
337       putchar('.');
338       fflush(stdout);
339       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
340     }
341   }
342   iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
343   iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
344   if(!tcadbclose(adb)){
345     eprint(adb, "tcadbclose");
346     err = true;
347   }
348   tcadbdel(adb);
349   iprintf("time: %.3f\n", tctime() - stime);
350   iprintf("%s\n\n", err ? "error" : "ok");
351   return err ? 1 : 0;
352 }
353
354
355 /* perform rcat command */
356 static int procrcat(const char *name, int rnum){
357   iprintf("<Random Concatenating Test>\n  name=%s  rnum=%d\n\n", name, rnum);
358   int pnum = rnum / 5 + 1;
359   bool err = false;
360   double stime = tctime();
361   TCADB *adb = tcadbnew();
362   if(!tcadbopen(adb, name)){
363     eprint(adb, "tcadbopen");
364     err = true;
365   }
366   for(int i = 1; i <= rnum; i++){
367     char kbuf[RECBUFSIZ];
368     int ksiz = sprintf(kbuf, "%d", myrand(pnum));
369     if(!tcadbputcat(adb, kbuf, ksiz, kbuf, ksiz)){
370       eprint(adb, "tcadbputcat");
371       err = true;
372       break;
373     }
374     if(rnum > 250 && i % (rnum / 250) == 0){
375       putchar('.');
376       fflush(stdout);
377       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
378     }
379   }
380   iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
381   iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
382   if(!tcadbclose(adb)){
383     eprint(adb, "tcadbclose");
384     err = true;
385   }
386   tcadbdel(adb);
387   iprintf("time: %.3f\n", tctime() - stime);
388   iprintf("%s\n\n", err ? "error" : "ok");
389   return err ? 1 : 0;
390 }
391
392
393 /* perform misc command */
394 static int procmisc(const char *name, int rnum){
395   iprintf("<Random Concatenating Test>\n  name=%s  rnum=%d\n\n", name, rnum);
396   bool err = false;
397   double stime = tctime();
398   TCADB *adb = tcadbnew();
399   if(!tcadbopen(adb, name)){
400     eprint(adb, "tcadbopen");
401     err = true;
402   }
403   iprintf("writing:\n");
404   for(int i = 1; i <= rnum; i++){
405     char buf[RECBUFSIZ];
406     int len = sprintf(buf, "%08d", i);
407     if(!tcadbputkeep(adb, buf, len, buf, len)){
408       eprint(adb, "tcadbputkeep");
409       err = true;
410       break;
411     }
412     if(rnum > 250 && i % (rnum / 250) == 0){
413       putchar('.');
414       fflush(stdout);
415       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
416     }
417   }
418   iprintf("reading:\n");
419   for(int i = 1; i <= rnum; i++){
420     char kbuf[RECBUFSIZ];
421     int ksiz = sprintf(kbuf, "%08d", i);
422     int vsiz;
423     char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
424     if(!vbuf){
425       eprint(adb, "tcadbget");
426       err = true;
427       break;
428     } else if(vsiz != ksiz || memcmp(vbuf, kbuf, vsiz)){
429       eprint(adb, "(validation)");
430       err = true;
431       free(vbuf);
432       break;
433     }
434     free(vbuf);
435     if(rnum > 250 && i % (rnum / 250) == 0){
436       putchar('.');
437       fflush(stdout);
438       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
439     }
440   }
441   if(tcadbrnum(adb) != rnum){
442     eprint(adb, "(validation)");
443     err = true;
444   }
445   iprintf("random writing:\n");
446   for(int i = 1; i <= rnum; i++){
447     char kbuf[RECBUFSIZ];
448     int ksiz = sprintf(kbuf, "%d", myrand(rnum));
449     char vbuf[RECBUFSIZ];
450     int vsiz = myrand(RECBUFSIZ);
451     memset(vbuf, '*', vsiz);
452     if(!tcadbput(adb, kbuf, ksiz, vbuf, vsiz)){
453       eprint(adb, "tcadbput");
454       err = true;
455       break;
456     }
457     int rsiz;
458     char *rbuf = tcadbget(adb, kbuf, ksiz, &rsiz);
459     if(!rbuf){
460       eprint(adb, "tcadbget");
461       err = true;
462       break;
463     }
464     if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){
465       eprint(adb, "(validation)");
466       err = true;
467       free(rbuf);
468       break;
469     }
470     if(rnum > 250 && i % (rnum / 250) == 0){
471       putchar('.');
472       fflush(stdout);
473       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
474     }
475     free(rbuf);
476   }
477   iprintf("word writing:\n");
478   const char *words[] = {
479     "a", "A", "bb", "BB", "ccc", "CCC", "dddd", "DDDD", "eeeee", "EEEEEE",
480     "mikio", "hirabayashi", "tokyo", "cabinet", "hyper", "estraier", "19780211", "birth day",
481     "one", "first", "two", "second", "three", "third", "four", "fourth", "five", "fifth",
482     "_[1]_", "uno", "_[2]_", "dos", "_[3]_", "tres", "_[4]_", "cuatro", "_[5]_", "cinco",
483     "[\xe5\xb9\xb3\xe6\x9e\x97\xe5\xb9\xb9\xe9\x9b\x84]", "[\xe9\xa6\xac\xe9\xb9\xbf]", NULL
484   };
485   for(int i = 0; words[i] != NULL; i += 2){
486     const char *kbuf = words[i];
487     int ksiz = strlen(kbuf);
488     const char *vbuf = words[i+1];
489     int vsiz = strlen(vbuf);
490     if(!tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz)){
491       eprint(adb, "tcadbputkeep");
492       err = true;
493       break;
494     }
495     if(rnum > 250) putchar('.');
496   }
497   if(rnum > 250) iprintf(" (%08d)\n", sizeof(words) / sizeof(*words));
498   iprintf("random erasing:\n");
499   for(int i = 1; i <= rnum; i++){
500     char kbuf[RECBUFSIZ];
501     int ksiz = sprintf(kbuf, "%d", myrand(rnum));
502     tcadbout(adb, kbuf, ksiz);
503     if(rnum > 250 && i % (rnum / 250) == 0){
504       putchar('.');
505       fflush(stdout);
506       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
507     }
508   }
509   iprintf("writing:\n");
510   for(int i = 1; i <= rnum; i++){
511     char kbuf[RECBUFSIZ];
512     int ksiz = sprintf(kbuf, "[%d]", i);
513     char vbuf[RECBUFSIZ];
514     int vsiz = i % RECBUFSIZ;
515     memset(vbuf, '*', vsiz);
516     if(!tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz)){
517       eprint(adb, "tcadbputkeep");
518       err = true;
519       break;
520     }
521     if(vsiz < 1){
522       char tbuf[PATH_MAX];
523       for(int j = 0; j < PATH_MAX; j++){
524         tbuf[j] = myrand(0x100);
525       }
526       if(!tcadbput(adb, kbuf, ksiz, tbuf, PATH_MAX)){
527         eprint(adb, "tcadbput");
528         err = true;
529         break;
530       }
531     }
532     if(rnum > 250 && i % (rnum / 250) == 0){
533       putchar('.');
534       fflush(stdout);
535       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
536     }
537   }
538   iprintf("erasing:\n");
539   for(int i = 1; i <= rnum; i++){
540     if(i % 2 == 1){
541       char kbuf[RECBUFSIZ];
542       int ksiz = sprintf(kbuf, "[%d]", i);
543       if(!tcadbout(adb, kbuf, ksiz)){
544         eprint(adb, "tcadbout");
545         err = true;
546         break;
547       }
548       tcadbout(adb, kbuf, ksiz);
549     }
550     if(rnum > 250 && i % (rnum / 250) == 0){
551       putchar('.');
552       fflush(stdout);
553       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
554     }
555   }
556   iprintf("iterator checking:\n");
557   if(!tcadbiterinit(adb)){
558     eprint(adb, "tcadbiterinit");
559     err = true;
560   }
561   char *kbuf;
562   int ksiz;
563   int inum = 0;
564   for(int i = 1; (kbuf = tcadbiternext(adb, &ksiz)) != NULL; i++, inum++){
565     int vsiz;
566     char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
567     if(!vbuf){
568       eprint(adb, "tcadbget");
569       err = true;
570       free(kbuf);
571       break;
572     }
573     free(vbuf);
574     free(kbuf);
575     if(rnum > 250 && i % (rnum / 250) == 0){
576       putchar('.');
577       fflush(stdout);
578       if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
579     }
580   }
581   if(rnum > 250) iprintf(" (%08d)\n", inum);
582   if(inum != tcadbrnum(adb)){
583     eprint(adb, "(validation)");
584     err = true;
585   }
586   if(*name != '*' && !tcadbsync(adb)){
587     eprint(adb, "tcadbsync");
588     err = true;
589   }
590   if(!tcadbvanish(adb)){
591     eprint(adb, "tcadbsync");
592     err = true;
593   }
594   iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
595   iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
596   if(!tcadbclose(adb)){
597     eprint(adb, "tcadbclose");
598     err = true;
599   }
600   tcadbdel(adb);
601   iprintf("time: %.3f\n", tctime() - stime);
602   iprintf("%s\n\n", err ? "error" : "ok");
603   return err ? 1 : 0;
604 }
605
606
607 /* perform wicked command */
608 static int procwicked(const char *name, int rnum){
609   iprintf("<Wicked Writing Test>\n  name=%s  rnum=%d\n\n", name, rnum);
610   bool err = false;
611   double stime = tctime();
612   TCADB *adb = tcadbnew();
613   if(!tcadbopen(adb, name)){
614     eprint(adb, "tcadbopen");
615     err = true;
616   }
617   TCMAP *map = tcmapnew2(rnum / 5);
618   for(int i = 1; i <= rnum && !err; i++){
619     char kbuf[RECBUFSIZ];
620     int ksiz = sprintf(kbuf, "%d", myrand(rnum));
621     char vbuf[RECBUFSIZ];
622     int vsiz = myrand(RECBUFSIZ);
623     memset(vbuf, '*', vsiz);
624     vbuf[vsiz] = '\0';
625     char *rbuf;
626     switch(myrand(16)){
627     case 0:
628       putchar('0');
629       if(!tcadbput(adb, kbuf, ksiz, vbuf, vsiz)){
630         eprint(adb, "tcadbput");
631         err = true;
632       }
633       tcmapput(map, kbuf, ksiz, vbuf, vsiz);
634       break;
635     case 1:
636       putchar('1');
637       if(!tcadbput2(adb, kbuf, vbuf)){
638         eprint(adb, "tcadbput2");
639         err = true;
640       }
641       tcmapput2(map, kbuf, vbuf);
642       break;
643     case 2:
644       putchar('2');
645       tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz);
646       tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz);
647       break;
648     case 3:
649       putchar('3');
650       tcadbputkeep2(adb, kbuf, vbuf);
651       tcmapputkeep2(map, kbuf, vbuf);
652       break;
653     case 4:
654       putchar('4');
655       if(!tcadbputcat(adb, kbuf, ksiz, vbuf, vsiz)){
656         eprint(adb, "tcadbputcat");
657         err = true;
658       }
659       tcmapputcat(map, kbuf, ksiz, vbuf, vsiz);
660       break;
661     case 5:
662       putchar('5');
663       if(!tcadbputcat2(adb, kbuf, vbuf)){
664         eprint(adb, "tcadbputcat2");
665         err = true;
666       }
667       tcmapputcat2(map, kbuf, vbuf);
668       break;
669     case 6:
670       putchar('6');
671       if(myrand(10) == 0){
672         tcadbout(adb, kbuf, ksiz);
673         tcmapout(map, kbuf, ksiz);
674       }
675       break;
676     case 7:
677       putchar('7');
678       if(myrand(10) == 0){
679         tcadbout2(adb, kbuf);
680         tcmapout2(map, kbuf);
681       }
682       break;
683     case 8:
684       putchar('8');
685       if((rbuf = tcadbget(adb, kbuf, ksiz, &vsiz)) != NULL) free(rbuf);
686       break;
687     case 9:
688       putchar('9');
689       if((rbuf = tcadbget2(adb, kbuf)) != NULL) free(rbuf);
690       break;
691     case 10:
692       putchar('A');
693       tcadbvsiz(adb, kbuf, ksiz);
694       break;
695     case 11:
696       putchar('B');
697       tcadbvsiz2(adb, kbuf);
698       break;
699     case 12:
700       putchar('E');
701       if(myrand(rnum / 50) == 0){
702         if(!tcadbiterinit(adb)){
703           eprint(adb, "tcadbiterinit");
704           err = true;
705         }
706       }
707       for(int j = myrand(rnum) / 1000 + 1; j >= 0; j--){
708         int iksiz;
709         char *ikbuf = tcadbiternext(adb, &iksiz);
710         if(ikbuf) free(ikbuf);
711       }
712       break;
713     default:
714       putchar('@');
715       if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX);
716       break;
717     }
718     if(i % 50 == 0) iprintf(" (%08d)\n", i);
719   }
720   if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum);
721   tcadbsync(adb);
722   if(tcadbrnum(adb) != tcmaprnum(map)){
723     eprint(adb, "(validation)");
724     err = true;
725   }
726   for(int i = 1; i <= rnum && !err; i++){
727     char kbuf[RECBUFSIZ];
728     int ksiz = sprintf(kbuf, "%d", i - 1);
729     int vsiz;
730     const char *vbuf = tcmapget(map, kbuf, ksiz, &vsiz);
731     int rsiz;
732     char *rbuf = tcadbget(adb, kbuf, ksiz, &rsiz);
733     if(vbuf){
734       putchar('.');
735       if(!rbuf){
736         eprint(adb, "tcadbget");
737         err = true;
738       } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){
739         eprint(adb, "(validation)");
740         err = true;
741       }
742     } else {
743       putchar('*');
744       if(rbuf){
745         eprint(adb, "(validation)");
746         err = true;
747       }
748     }
749     free(rbuf);
750     if(i % 50 == 0) iprintf(" (%08d)\n", i);
751   }
752   if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum);
753   tcmapiterinit(map);
754   int ksiz;
755   const char *kbuf;
756   for(int i = 1; (kbuf = tcmapiternext(map, &ksiz)) != NULL; i++){
757     putchar('+');
758     int vsiz;
759     const char *vbuf = tcmapiterval(kbuf, &vsiz);
760     int rsiz;
761     char *rbuf = tcadbget(adb, kbuf, ksiz, &rsiz);
762     if(!rbuf){
763       eprint(adb, "tcadbget");
764       err = true;
765     } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){
766       eprint(adb, "(validation)");
767       err = true;
768     }
769     free(rbuf);
770     if(!tcadbout(adb, kbuf, ksiz)){
771       eprint(adb, "tcadbout");
772       err = true;
773     }
774     if(i % 50 == 0) iprintf(" (%08d)\n", i);
775   }
776   int mrnum = tcmaprnum(map);
777   if(mrnum % 50 > 0) iprintf(" (%08d)\n", mrnum);
778   if(tcadbrnum(adb) != 0){
779     eprint(adb, "(validation)");
780     err = true;
781   }
782   iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
783   iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
784   tcmapdel(map);
785   if(!tcadbclose(adb)){
786     eprint(adb, "tcadbclose");
787     err = true;
788   }
789   tcadbdel(adb);
790   iprintf("time: %.3f\n", tctime() - stime);
791   iprintf("%s\n\n", err ? "error" : "ok");
792   return err ? 1 : 0;
793 }
794
795
796
797 // END OF FILE