1 /*************************************************************************************************
2 * Test cases of Villa
3 * Copyright (C) 2000-2007 Mikio Hirabayashi
4 * This file is part of QDBM, Quick Database Manager.
5 * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * Lesser General Public License as published by the Free Software Foundation; either version
7 * 2.1 of the License or any later version. QDBM is distributed in the hope that it will be
8 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
10 * details.
11 * You should have received a copy of the GNU Lesser General Public License along with QDBM; if
12 * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
13 * 02111-1307 USA.
14 *************************************************************************************************/
15
16
17 #include <depot.h>
18 #include <cabin.h>
19 #include <villa.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #include <limits.h>
25 #include <time.h>
26
27 #undef TRUE
28 #define TRUE 1 /* boolean true */
29 #undef FALSE
30 #define FALSE 0 /* boolean false */
31
32 #define RECBUFSIZ 32 /* buffer for records */
33
34
35 /* for RISC OS */
36 #if defined(__riscos__) || defined(__riscos)
37 #include <unixlib/local.h>
38 int __riscosify_control = __RISCOSIFY_NO_PROCESS;
39 #endif
40
41
42 /* global variables */
43 const char *progname; /* program name */
44
45
46 /* function prototypes */
47 int main(int argc, char **argv);
48 void usage(void);
49 int runwrite(int argc, char **argv);
50 int runread(int argc, char **argv);
51 int runrdup(int argc, char **argv);
52 int runcombo(int argc, char **argv);
53 int runwicked(int argc, char **argv);
54 int printfflush(const char *format, ...);
55 void pdperror(const char *name);
56 int myrand(void);
57 int dowrite(const char *name, int rnum, int ii, int cmode,
58 int lrecmax, int nidxmax, int lcnum, int ncnum, int fbp);
59 int doread(const char *name, int ii, int vc);
60 int dordup(const char *name, int rnum, int pnum, int ii, int cmode, int cc,
61 int lrecmax, int nidxmax, int lcnum, int ncnum, int fbp);
62 int docombo(const char *name, int cmode);
63 int dowicked(const char *name, int rnum, int cb, int cmode);
64
65
66 /* main routine */
main(int argc,char ** argv)67 int main(int argc, char **argv){
68 char *env;
69 int rv;
70 cbstdiobin();
71 if((env = getenv("QDBMDBGFD")) != NULL) dpdbgfd = atoi(env);
72 progname = argv[0];
73 if(argc < 2) usage();
74 rv = 0;
75 if(!strcmp(argv[1], "write")){
76 rv = runwrite(argc, argv);
77 } else if(!strcmp(argv[1], "read")){
78 rv = runread(argc, argv);
79 } else if(!strcmp(argv[1], "rdup")){
80 rv = runrdup(argc, argv);
81 } else if(!strcmp(argv[1], "combo")){
82 rv = runcombo(argc, argv);
83 } else if(!strcmp(argv[1], "wicked")){
84 rv = runwicked(argc, argv);
85 } else {
86 usage();
87 }
88 return rv;
89 }
90
91
92 /* print the usage and exit */
usage(void)93 void usage(void){
94 fprintf(stderr, "%s: test cases for Villa\n", progname);
95 fprintf(stderr, "\n");
96 fprintf(stderr, "usage:\n");
97 fprintf(stderr, " %s write [-int] [-cz|-cy|-cx] [-tune lrecmax nidxmax lcnum ncnum]"
98 " [-fbp num] name rnum\n", progname);
99 fprintf(stderr, " %s read [-int] [-vc] name\n", progname);
100 fprintf(stderr, " %s rdup [-int] [-cz|-cy|-cx] [-cc] [-tune lrecmax nidxmax lcnum ncnum]"
101 " [-fbp num] name rnum pnum\n", progname);
102 fprintf(stderr, " %s combo [-cz|-cy|-cx] name\n", progname);
103 fprintf(stderr, " %s wicked [-c] [-cz|-cy|-cx] name rnum\n", progname);
104 fprintf(stderr, "\n");
105 exit(1);
106 }
107
108
109 /* parse arguments of write command */
runwrite(int argc,char ** argv)110 int runwrite(int argc, char **argv){
111 char *name, *rstr;
112 int i, rnum, ii, cmode, lrecmax, nidxmax, lcnum, ncnum, fbp, rv;
113 name = NULL;
114 rstr = NULL;
115 rnum = 0;
116 ii = FALSE;
117 cmode = 0;
118 lrecmax = -1;
119 nidxmax = -1;
120 lcnum = -1;
121 ncnum = -1;
122 fbp = -1;
123 for(i = 2; i < argc; i++){
124 if(!name && argv[i][0] == '-'){
125 if(!strcmp(argv[i], "-int")){
126 ii = TRUE;
127 } else if(!strcmp(argv[i], "-cz")){
128 cmode |= VL_OZCOMP;
129 } else if(!strcmp(argv[i], "-cy")){
130 cmode |= VL_OYCOMP;
131 } else if(!strcmp(argv[i], "-cx")){
132 cmode |= VL_OXCOMP;
133 } else if(!strcmp(argv[i], "-tune")){
134 if(++i >= argc) usage();
135 lrecmax = atoi(argv[i]);
136 if(++i >= argc) usage();
137 nidxmax = atoi(argv[i]);
138 if(++i >= argc) usage();
139 lcnum = atoi(argv[i]);
140 if(++i >= argc) usage();
141 ncnum = atoi(argv[i]);
142 } else if(!strcmp(argv[i], "-fbp")){
143 if(++i >= argc) usage();
144 fbp = atoi(argv[i]);
145 } else {
146 usage();
147 }
148 } else if(!name){
149 name = argv[i];
150 } else if(!rstr){
151 rstr = argv[i];
152 } else {
153 usage();
154 }
155 }
156 if(!name || !rstr) usage();
157 rnum = atoi(rstr);
158 if(rnum < 1) usage();
159 rv = dowrite(name, rnum, ii, cmode, lrecmax, nidxmax, lcnum, ncnum, fbp);
160 return rv;
161 }
162
163
164 /* parse arguments of read command */
runread(int argc,char ** argv)165 int runread(int argc, char **argv){
166 char *name;
167 int i, ii, vc, rv;
168 name = NULL;
169 ii = FALSE;
170 vc = FALSE;
171 for(i = 2; i < argc; i++){
172 if(!name && argv[i][0] == '-'){
173 if(!strcmp(argv[i], "-int")){
174 ii = TRUE;
175 } else if(!strcmp(argv[i], "-vc")){
176 vc = TRUE;
177 } else {
178 usage();
179 }
180 } else if(!name){
181 name = argv[i];
182 } else {
183 usage();
184 }
185 }
186 if(!name) usage();
187 rv = doread(name, ii, vc);
188 return rv;
189 }
190
191
192 /* parse arguments of rdup command */
runrdup(int argc,char ** argv)193 int runrdup(int argc, char **argv){
194 char *name, *rstr, *pstr;
195 int i, rnum, pnum, ii, cmode, cc, lrecmax, nidxmax, lcnum, ncnum, fbp, rv;
196 name = NULL;
197 rstr = NULL;
198 pstr = NULL;
199 rnum = 0;
200 pnum = 0;
201 ii = FALSE;
202 cmode = 0;
203 cc = FALSE;
204 lrecmax = -1;
205 nidxmax = -1;
206 lcnum = -1;
207 ncnum = -1;
208 fbp = -1;
209 for(i = 2; i < argc; i++){
210 if(!name && argv[i][0] == '-'){
211 if(!strcmp(argv[i], "-int")){
212 ii = TRUE;
213 } else if(!strcmp(argv[i], "-cz")){
214 cmode |= VL_OZCOMP;
215 } else if(!strcmp(argv[i], "-cy")){
216 cmode |= VL_OYCOMP;
217 } else if(!strcmp(argv[i], "-cx")){
218 cmode |= VL_OXCOMP;
219 } else if(!strcmp(argv[i], "-cc")){
220 cc = TRUE;
221 } else if(!strcmp(argv[i], "-tune")){
222 if(++i >= argc) usage();
223 lrecmax = atoi(argv[i]);
224 if(++i >= argc) usage();
225 nidxmax = atoi(argv[i]);
226 if(++i >= argc) usage();
227 lcnum = atoi(argv[i]);
228 if(++i >= argc) usage();
229 ncnum = atoi(argv[i]);
230 } else if(!strcmp(argv[i], "-fbp")){
231 if(++i >= argc) usage();
232 fbp = atoi(argv[i]);
233 } else {
234 usage();
235 }
236 } else if(!name){
237 name = argv[i];
238 } else if(!rstr){
239 rstr = argv[i];
240 } else if(!pstr){
241 pstr = argv[i];
242 } else {
243 usage();
244 }
245 }
246 if(!name || !rstr || !pstr) usage();
247 rnum = atoi(rstr);
248 pnum = atoi(pstr);
249 if(rnum < 1 || pnum < 1) usage();
250 rv = dordup(name, rnum, pnum, ii, cmode, cc, lrecmax, nidxmax, lcnum, ncnum, fbp);
251 return rv;
252 }
253
254
255 /* parse arguments of combo command */
runcombo(int argc,char ** argv)256 int runcombo(int argc, char **argv){
257 char *name;
258 int i, cmode, rv;
259 name = NULL;
260 cmode = 0;
261 for(i = 2; i < argc; i++){
262 if(!name && argv[i][0] == '-'){
263 if(!strcmp(argv[i], "-cz")){
264 cmode |= VL_OZCOMP;
265 } else if(!strcmp(argv[i], "-cy")){
266 cmode |= VL_OYCOMP;
267 } else if(!strcmp(argv[i], "-cx")){
268 cmode |= VL_OXCOMP;
269 } else {
270 usage();
271 }
272 } else if(!name){
273 name = argv[i];
274 } else {
275 usage();
276 }
277 }
278 if(!name) usage();
279 rv = docombo(name, cmode);
280 return rv;
281 }
282
283
284 /* parse arguments of wicked command */
runwicked(int argc,char ** argv)285 int runwicked(int argc, char **argv){
286 char *name, *rstr;
287 int i, cb, cmode, rnum, rv;
288 name = NULL;
289 rstr = NULL;
290 cb = FALSE;
291 cmode = 0;
292 for(i = 2; i < argc; i++){
293 if(!name && argv[i][0] == '-'){
294 if(!strcmp(argv[i], "-c")){
295 cb = TRUE;
296 } else if(!strcmp(argv[i], "-cz")){
297 cmode |= VL_OZCOMP;
298 } else if(!strcmp(argv[i], "-cy")){
299 cmode |= VL_OYCOMP;
300 } else if(!strcmp(argv[i], "-cx")){
301 cmode |= VL_OXCOMP;
302 } else {
303 usage();
304 }
305 } else if(!name){
306 name = argv[i];
307 } else if(!rstr){
308 rstr = argv[i];
309 } else {
310 usage();
311 }
312 }
313 if(!name || !rstr) usage();
314 rnum = atoi(rstr);
315 if(rnum < 1) usage();
316 rv = dowicked(name, rnum, cb, cmode);
317 return rv;
318 }
319
320
321 /* print formatted string and flush the buffer */
printfflush(const char * format,...)322 int printfflush(const char *format, ...){
323 va_list ap;
324 int rv;
325 va_start(ap, format);
326 rv = vprintf(format, ap);
327 if(fflush(stdout) == EOF) rv = -1;
328 va_end(ap);
329 return rv;
330 }
331
332
333 /* print an error message */
pdperror(const char * name)334 void pdperror(const char *name){
335 fprintf(stderr, "%s: %s: %s\n", progname, name, dperrmsg(dpecode));
336 }
337
338
339 /* pseudo random number generator */
myrand(void)340 int myrand(void){
341 static int cnt = 0;
342 if(cnt == 0) srand(time(NULL));
343 return (rand() * rand() + (rand() >> (sizeof(int) * 4)) + (cnt++)) & INT_MAX;
344 }
345
346
347 /* perform write command */
dowrite(const char * name,int rnum,int ii,int cmode,int lrecmax,int nidxmax,int lcnum,int ncnum,int fbp)348 int dowrite(const char *name, int rnum, int ii, int cmode,
349 int lrecmax, int nidxmax, int lcnum, int ncnum, int fbp){
350 VILLA *villa;
351 int i, omode, err, len;
352 char buf[RECBUFSIZ];
353 printfflush("<Writing Test>\n name=%s rnum=%d int=%d cmode=%d "
354 "lrecmax=%d nidxmax=%d lcnum=%d ncnum=%d fbp=%d\n\n",
355 name, rnum, ii, cmode, lrecmax, nidxmax, lcnum, ncnum, fbp);
356 /* open a database */
357 omode = VL_OWRITER | VL_OCREAT | VL_OTRUNC | cmode;
358 if(!(villa = vlopen(name, omode, ii ? VL_CMPINT : VL_CMPLEX))){
359 pdperror(name);
360 return 1;
361 }
362 err = FALSE;
363 /* set tuning parameters */
364 if(lrecmax > 0) vlsettuning(villa, lrecmax, nidxmax, lcnum, ncnum);
365 if(fbp >= 0) vlsetfbpsiz(villa, fbp);
366 /* loop for each record */
367 for(i = 1; i <= rnum; i++){
368 /* store a record */
369 if(ii){
370 if(!vlput(villa, (char *)&i, sizeof(int), (char *)&i, sizeof(int), VL_DOVER)){
371 pdperror(name);
372 err = TRUE;
373 break;
374 }
375 } else {
376 len = sprintf(buf, "%08d", i);
377 if(!vlput(villa, buf, len, buf, len, VL_DOVER)){
378 pdperror(name);
379 err = TRUE;
380 break;
381 }
382 }
383 /* print progression */
384 if(rnum > 250 && i % (rnum / 250) == 0){
385 putchar('.');
386 fflush(stdout);
387 if(i == rnum || i % (rnum / 10) == 0){
388 printfflush(" (%08d)\n", i);
389 }
390 }
391 }
392 /* close the database */
393 if(!vlclose(villa)){
394 pdperror(name);
395 return 1;
396 }
397 if(!err) printfflush("ok\n\n");
398 return 0;
399 }
400
401
402 /* perform read command */
doread(const char * name,int ii,int vc)403 int doread(const char *name, int ii, int vc){
404 VILLA *villa;
405 int i, rnum, err, len;
406 const char *cval;
407 char buf[RECBUFSIZ], *val;
408 printfflush("<Reading Test>\n name=%s int=%d\n\n", name, ii);
409 /* open a database */
410 if(!(villa = vlopen(name, VL_OREADER, ii ? VL_CMPINT : VL_CMPLEX))){
411 pdperror(name);
412 return 1;
413 }
414 /* get the number of records */
415 rnum = vlrnum(villa);
416 err = FALSE;
417 /* loop for each record */
418 for(i = 1; i <= rnum; i++){
419 /* retrieve a record */
420 if(ii){
421 if(vc){
422 if(!(cval = vlgetcache(villa, (char *)&i, sizeof(int), NULL))){
423 pdperror(name);
424 err = TRUE;
425 break;
426 }
427 } else {
428 if(!(val = vlget(villa, (char *)&i, sizeof(int), NULL))){
429 pdperror(name);
430 err = TRUE;
431 break;
432 }
433 free(val);
434 }
435 } else {
436 len = sprintf(buf, "%08d", i);
437 if(vc){
438 if(!(cval = vlgetcache(villa, buf, len, NULL))){
439 pdperror(name);
440 err = TRUE;
441 break;
442 }
443 } else {
444 if(!(val = vlget(villa, buf, len, NULL))){
445 pdperror(name);
446 err = TRUE;
447 break;
448 }
449 free(val);
450 }
451 }
452 /* print progression */
453 if(rnum > 250 && i % (rnum / 250) == 0){
454 putchar('.');
455 fflush(stdout);
456 if(i == rnum || i % (rnum / 10) == 0){
457 printfflush(" (%08d)\n", i);
458 }
459 }
460 }
461 /* close the database */
462 if(!vlclose(villa)){
463 pdperror(name);
464 return 1;
465 }
466 if(!err) printfflush("ok\n\n");
467 return 0;
468 }
469
470
471 /* perform rdup command */
dordup(const char * name,int rnum,int pnum,int ii,int cmode,int cc,int lrecmax,int nidxmax,int lcnum,int ncnum,int fbp)472 int dordup(const char *name, int rnum, int pnum, int ii, int cmode, int cc,
473 int lrecmax, int nidxmax, int lcnum, int ncnum, int fbp){
474 VILLA *villa;
475 int i, omode, err, dmode, vi, len;
476 char buf[RECBUFSIZ];
477 printfflush("<Random Writing Test>\n name=%s rnum=%d int=%d cmode=%d "
478 "lrecmax=%d nidxmax=%d lcnum=%d ncnum=%d fbp=%d\n\n",
479 name, rnum, ii, cmode, lrecmax, nidxmax, lcnum, ncnum, fbp);
480 omode = VL_OWRITER | VL_OCREAT | VL_OTRUNC | cmode;
481 if(!(villa = vlopen(name, omode, ii ? VL_CMPINT : VL_CMPLEX))){
482 pdperror(name);
483 return 1;
484 }
485 err = FALSE;
486 if(lrecmax > 0) vlsettuning(villa, lrecmax, nidxmax, lcnum, ncnum);
487 if(fbp >= 0) vlsetfbpsiz(villa, fbp);
488 for(i = 1; i <= rnum; i++){
489 dmode = i % 3 == 0 ? VL_DDUPR : VL_DDUP;
490 if(cc && myrand() % 2 == 0) dmode = VL_DCAT;
491 vi = myrand() % pnum + 1;
492 if(ii){
493 if(!vlput(villa, (char *)&vi, sizeof(int), (char *)&vi, sizeof(int), dmode)){
494 pdperror(name);
495 err = TRUE;
496 break;
497 }
498 } else {
499 len = sprintf(buf, "%08d", vi);
500 if(!vlput(villa, buf, len, buf, len, dmode)){
501 pdperror(name);
502 err = TRUE;
503 break;
504 }
505 }
506 if(rnum > 250 && i % (rnum / 250) == 0){
507 putchar('.');
508 fflush(stdout);
509 if(i == rnum || i % (rnum / 10) == 0){
510 printfflush(" (%08d: fsiz=%d lnum=%d nnum=%d)\n",
511 i, vlfsiz(villa), vllnum(villa), vlnnum(villa));
512 }
513 }
514 }
515 if(!vlclose(villa)){
516 pdperror(name);
517 return 1;
518 }
519 if(!err) printfflush("ok\n\n");
520 return 0;
521 }
522
523
524 /* perform combo command */
docombo(const char * name,int cmode)525 int docombo(const char *name, int cmode){
526 VILLA *villa;
527 VLMULCUR **mulcurs;
528 char buf[RECBUFSIZ], *vbuf, *kbuf;
529 int i, j, omode, len, vsiz, ksiz, fsiz, lnum, nnum, rnum;
530 CBLIST *alist, *dlist;
531 const char *ap, *dp;
532 printfflush("<Combination Test>\n name=%s cmode=%d\n\n", name, cmode);
533 printfflush("Creating a database with VL_CMPLEX ... ");
534 omode = VL_OWRITER | VL_OCREAT | VL_OTRUNC | cmode;
535 if(!(villa = vlopen(name, omode, VL_CMPLEX))){
536 pdperror(name);
537 return 1;
538 }
539 printfflush("ok\n");
540 printfflush("Setting tuning parameters with 3, 4, 16, 16 ... ");
541 vlsettuning(villa, 3, 4, 16, 16);
542 printfflush("ok\n");
543 printfflush("Adding 100 records with VL_DOVER ... ");
544 for(i = 1; i <= 100; i++){
545 len = sprintf(buf, "%08d", i);
546 if(!vlput(villa, buf, len, buf, len, VL_DOVER)){
547 pdperror(name);
548 vlclose(villa);
549 return 1;
550 }
551 }
552 printfflush("ok\n");
553 printfflush("Checking records ... ");
554 for(i = 1; i <= 100; i++){
555 len = sprintf(buf, "%08d", i);
556 if(!(vbuf = vlget(villa, buf, len, &vsiz))){
557 pdperror(name);
558 vlclose(villa);
559 return 1;
560 }
561 free(vbuf);
562 if(vsiz != 8 || vlvsiz(villa, buf, len) != 8){
563 fprintf(stderr, "%s: %s: invalid vsiz\n", progname, name);
564 vlclose(villa);
565 return 1;
566 }
567 if(vlvnum(villa, buf, len) != 1){
568 fprintf(stderr, "%s: %s: invalid vnum\n", progname, name);
569 vlclose(villa);
570 return 1;
571 }
572 }
573 printfflush("ok\n");
574 printfflush("Deleting x1 - x5 records ... ");
575 for(i = 1; i <= 100; i++){
576 if(i % 10 < 1 || i % 10 > 5) continue;
577 len = sprintf(buf, "%08d", i);
578 if(!vlout(villa, buf, len)){
579 pdperror(name);
580 vlclose(villa);
581 return 1;
582 }
583 }
584 printfflush("ok\n");
585 printfflush("Adding 100 records with VL_DOVER ... ");
586 for(i = 1; i <= 100; i++){
587 len = sprintf(buf, "%08d", i);
588 if(!vlput(villa, buf, len, buf, len, VL_DOVER)){
589 pdperror(name);
590 vlclose(villa);
591 return 1;
592 }
593 }
594 printfflush("ok\n");
595 printfflush("Deleting x1 - x5 records ... ");
596 for(i = 1; i <= 100; i++){
597 if(i % 10 < 1 || i % 10 > 5) continue;
598 len = sprintf(buf, "%08d", i);
599 if(!vlout(villa, buf, len)){
600 pdperror(name);
601 vlclose(villa);
602 return 1;
603 }
604 }
605 printfflush("ok\n");
606 printfflush("Checking number of records ... ");
607 if(vlrnum(villa) != 50){
608 fprintf(stderr, "%s: %s: invalid rnum\n", progname, name);
609 vlclose(villa);
610 return 1;
611 }
612 printfflush("ok\n");
613 printfflush("Adding 100 records with VL_DDUP ... ");
614 for(i = 1; i <= 100; i++){
615 len = sprintf(buf, "%08d", i);
616 if(!vlput(villa, buf, len, buf, len, VL_DDUP)){
617 pdperror(name);
618 vlclose(villa);
619 return 1;
620 }
621 }
622 printfflush("ok\n");
623 printfflush("Deleting x6 - x0 records ... ");
624 for(i = 1; i <= 100; i++){
625 if(i % 10 >= 1 && i % 10 <= 5) continue;
626 len = sprintf(buf, "%08d", i);
627 if(!vlout(villa, buf, len)){
628 pdperror(name);
629 vlclose(villa);
630 return 1;
631 }
632 }
633 printfflush("ok\n");
634 printfflush("Optimizing the database ... ");
635 if(!vloptimize(villa)){
636 pdperror(name);
637 vlclose(villa);
638 return 1;
639 }
640 printfflush("ok\n");
641 printfflush("Checking number of records ... ");
642 if(vlrnum(villa) != 100){
643 fprintf(stderr, "%s: %s: invalid rnum\n", progname, name);
644 vlclose(villa);
645 return 1;
646 }
647 printfflush("ok\n");
648 printfflush("Checking records ... ");
649 for(i = 1; i <= 100; i++){
650 len = sprintf(buf, "%08d", i);
651 if(!(vbuf = vlget(villa, buf, len, &vsiz))){
652 pdperror(name);
653 vlclose(villa);
654 return 1;
655 }
656 free(vbuf);
657 if(vsiz != 8){
658 fprintf(stderr, "%s: %s: invalid vsiz\n", progname, name);
659 vlclose(villa);
660 return 1;
661 }
662 if(vlvnum(villa, buf, len) != 1){
663 fprintf(stderr, "%s: %s: invalid vnum\n", progname, name);
664 vlclose(villa);
665 return 1;
666 }
667 }
668 printfflush("ok\n");
669 printfflush("Deleting x6 - x0 records ... ");
670 for(i = 1; i <= 100; i++){
671 if(i % 10 >= 1 && i % 10 <= 5) continue;
672 len = sprintf(buf, "%08d", i);
673 if(!vlout(villa, buf, len)){
674 pdperror(name);
675 vlclose(villa);
676 return 1;
677 }
678 }
679 printfflush("ok\n");
680 printfflush("Scanning with the cursor in ascending order ... ");
681 if(!vlcurfirst(villa)){
682 pdperror(name);
683 vlclose(villa);
684 return 1;
685 }
686 i = 0;
687 do {
688 kbuf = NULL;
689 vbuf = NULL;
690 if(!(kbuf = vlcurkey(villa, &ksiz)) || !(vbuf = vlcurval(villa, &vsiz))){
691 pdperror(name);
692 free(kbuf);
693 free(vbuf);
694 vlclose(villa);
695 return 1;
696 }
697 free(kbuf);
698 free(vbuf);
699 i++;
700 } while(vlcurnext(villa));
701 if(i != 50){
702 fprintf(stderr, "%s: %s: invalid cursor\n", progname, name);
703 vlclose(villa);
704 return 1;
705 }
706 if(dpecode != DP_ENOITEM){
707 pdperror(name);
708 vlclose(villa);
709 return 1;
710 }
711 printfflush("ok\n");
712 printfflush("Scanning with the cursor in decending order ... ");
713 if(!vlcurlast(villa)){
714 pdperror(name);
715 vlclose(villa);
716 return 1;
717 }
718 i = 0;
719 do {
720 kbuf = NULL;
721 vbuf = NULL;
722 if(!(kbuf = vlcurkey(villa, &ksiz)) || !(vbuf = vlcurval(villa, &vsiz))){
723 pdperror(name);
724 free(kbuf);
725 free(vbuf);
726 vlclose(villa);
727 return 1;
728 }
729 free(kbuf);
730 free(vbuf);
731 i++;
732 } while(vlcurprev(villa));
733 if(i != 50){
734 fprintf(stderr, "%s: %s: invalid cursor\n", progname, name);
735 vlclose(villa);
736 return 1;
737 }
738 if(dpecode != DP_ENOITEM){
739 pdperror(name);
740 vlclose(villa);
741 return 1;
742 }
743 printfflush("ok\n");
744 printfflush("Adding 50 random records with VL_DDUPR ... ");
745 for(i = 0; i < 50; i++){
746 len = sprintf(buf, "%08d", myrand() % 100 + 1);
747 if(!vlput(villa, buf, len, buf, len, VL_DDUPR)){
748 pdperror(name);
749 vlclose(villa);
750 return 1;
751 }
752 }
753 printfflush("ok\n");
754 printfflush("Deleting 80 random records ... ");
755 i = 0;
756 while(i < 80){
757 len = sprintf(buf, "%08d", myrand() % 100 + 1);
758 if(!vlout(villa, buf, len)){
759 if(dpecode == DP_ENOITEM) continue;
760 pdperror(name);
761 vlclose(villa);
762 return 1;
763 }
764 i++;
765 }
766 printfflush("ok\n");
767 alist = cblistopen();
768 dlist = cblistopen();
769 printfflush("Scanning with the cursor in ascending order ... ");
770 if(!vlcurfirst(villa)){
771 pdperror(name);
772 vlclose(villa);
773 return 1;
774 }
775 i = 0;
776 do {
777 kbuf = NULL;
778 vbuf = NULL;
779 if(!(kbuf = vlcurkey(villa, &ksiz)) || !(vbuf = vlcurval(villa, &vsiz))){
780 pdperror(name);
781 cblistclose(alist);
782 cblistclose(dlist);
783 free(kbuf);
784 free(vbuf);
785 vlclose(villa);
786 return 1;
787 }
788 cblistpush(alist, kbuf, ksiz);
789 free(kbuf);
790 free(vbuf);
791 i++;
792 } while(vlcurnext(villa));
793 if(i != 20){
794 fprintf(stderr, "%s: %s: invalid cursor\n", progname, name);
795 cblistclose(alist);
796 cblistclose(dlist);
797 vlclose(villa);
798 return 1;
799 }
800 if(dpecode != DP_ENOITEM){
801 pdperror(name);
802 cblistclose(alist);
803 cblistclose(dlist);
804 vlclose(villa);
805 return 1;
806 }
807 printfflush("ok\n");
808 printfflush("Scanning with the cursor in decending order ... ");
809 if(!vlcurlast(villa)){
810 pdperror(name);
811 cblistclose(alist);
812 cblistclose(dlist);
813 vlclose(villa);
814 return 1;
815 }
816 i = 0;
817 do {
818 kbuf = NULL;
819 vbuf = NULL;
820 if(!(kbuf = vlcurkey(villa, &ksiz)) || !(vbuf = vlcurval(villa, &vsiz))){
821 pdperror(name);
822 free(kbuf);
823 free(vbuf);
824 cblistclose(alist);
825 cblistclose(dlist);
826 vlclose(villa);
827 return 1;
828 }
829 cblistunshift(dlist, kbuf, ksiz);
830 free(kbuf);
831 free(vbuf);
832 i++;
833 } while(vlcurprev(villa));
834 if(i != 20){
835 fprintf(stderr, "%s: %s: invalid cursor\n", progname, name);
836 cblistclose(alist);
837 cblistclose(dlist);
838 vlclose(villa);
839 return 1;
840 }
841 if(dpecode != DP_ENOITEM){
842 pdperror(name);
843 cblistclose(alist);
844 cblistclose(dlist);
845 vlclose(villa);
846 return 1;
847 }
848 printfflush("ok\n");
849 printfflush("Matching result of ascending scan and desending scan ... ");
850 for(i = 0; i < cblistnum(alist); i++){
851 ap = cblistval(alist, i, NULL);
852 dp = cblistval(dlist, i, NULL);
853 if(strcmp(ap, dp)){
854 fprintf(stderr, "%s: %s: not match\n", progname, name);
855 cblistclose(alist);
856 cblistclose(dlist);
857 vlclose(villa);
858 return 1;
859 }
860 }
861 cblistsort(alist);
862 for(i = 0; i < cblistnum(alist); i++){
863 ap = cblistval(alist, i, NULL);
864 dp = cblistval(dlist, i, NULL);
865 if(strcmp(ap, dp)){
866 fprintf(stderr, "%s: %s: not match\n", progname, name);
867 cblistclose(alist);
868 cblistclose(dlist);
869 vlclose(villa);
870 return 1;
871 }
872 }
873 printfflush("ok\n");
874 cblistclose(alist);
875 cblistclose(dlist);
876 printfflush("Resetting tuning parameters with 41, 80, 32, 32 ... ");
877 vlsettuning(villa, 41, 80, 32, 32);
878 printfflush("ok\n");
879 printfflush("Adding 1000 random records with VL_DDUP ... ");
880 for(i = 0; i < 1000; i++){
881 len = sprintf(buf, "%08d", myrand() % 1000 + 1);
882 if(!vlput(villa, buf, len, buf, len, VL_DDUP)){
883 pdperror(name);
884 vlclose(villa);
885 return 1;
886 }
887 }
888 printfflush("ok\n");
889 printfflush("Resetting tuning parameters with 8, 5, 16, 16 ... ");
890 vlsettuning(villa, 8, 5, 16, 16);
891 printfflush("ok\n");
892 printfflush("Adding 1000 random records with VL_DDUP ... ");
893 for(i = 0; i < 1000; i++){
894 len = sprintf(buf, "%08d", myrand() % 1000 + 1);
895 if(!vlput(villa, buf, len, buf, len, VL_DDUP)){
896 pdperror(name);
897 vlclose(villa);
898 return 1;
899 }
900 }
901 printfflush("ok\n");
902 printfflush("Beginning the transaction ... ");
903 if(!vltranbegin(villa)){
904 pdperror(name);
905 vlclose(villa);
906 return 1;
907 }
908 printfflush("ok\n");
909 printfflush("Adding 100 random records with VL_DDUP ... ");
910 for(i = 0; i < 100; i++){
911 len = sprintf(buf, "%08d", myrand() % 1000 + 1);
912 if(!vlput(villa, buf, len, buf, len, VL_DDUP)){
913 pdperror(name);
914 vlclose(villa);
915 return 1;
916 }
917 }
918 printfflush("ok\n");
919 printfflush("Scanning and checking ... ");
920 i = 0;
921 for(vlcurlast(villa); (kbuf = vlcurkey(villa, &ksiz)) != NULL; vlcurprev(villa)){
922 if(vlvnum(villa, kbuf, ksiz) < 1 || !(vbuf = vlcurval(villa, NULL))){
923 pdperror(name);
924 free(kbuf);
925 vlclose(villa);
926 return 1;
927 }
928 free(vbuf);
929 free(kbuf);
930 i++;
931 }
932 if(i != vlrnum(villa)){
933 fprintf(stderr, "%s: %s: invalid\n", progname, name);
934 vlclose(villa);
935 return 1;
936 }
937 printfflush("ok\n");
938 printfflush("Committing the transaction ... ");
939 if(!vltrancommit(villa)){
940 pdperror(name);
941 vlclose(villa);
942 return 1;
943 }
944 printfflush("ok\n");
945 printfflush("Scanning and checking ... ");
946 i = 0;
947 for(vlcurlast(villa); (kbuf = vlcurkey(villa, &ksiz)) != NULL; vlcurprev(villa)){
948 if(vlvnum(villa, kbuf, ksiz) < 1 || !(vbuf = vlcurval(villa, NULL))){
949 pdperror(name);
950 free(kbuf);
951 vlclose(villa);
952 return 1;
953 }
954 free(vbuf);
955 free(kbuf);
956 i++;
957 }
958 if(i != vlrnum(villa)){
959 fprintf(stderr, "%s: %s: invalid\n", progname, name);
960 vlclose(villa);
961 return 1;
962 }
963 printfflush("ok\n");
964 lnum = vllnum(villa);
965 nnum = vlnnum(villa);
966 rnum = vlrnum(villa);
967 fsiz = vlfsiz(villa);
968 printfflush("Beginning the transaction ... ");
969 if(!vltranbegin(villa)){
970 pdperror(name);
971 vlclose(villa);
972 return 1;
973 }
974 printfflush("ok\n");
975 printfflush("Adding 100 random records with VL_DDUP ... ");
976 for(i = 0; i < 100; i++){
977 len = sprintf(buf, "%08d", myrand() % 1000 + 1);
978 if(!vlput(villa, buf, len, buf, len, VL_DDUP)){
979 pdperror(name);
980 vlclose(villa);
981 return 1;
982 }
983 }
984 printfflush("ok\n");
985 printfflush("Aborting the transaction ... ");
986 if(!vltranabort(villa)){
987 pdperror(name);
988 vlclose(villa);
989 return 1;
990 }
991 printfflush("ok\n");
992 printfflush("Checking rollback ... ");
993 if(vlfsiz(villa) != fsiz || vllnum(villa) != lnum ||
994 vlnnum(villa) != nnum || vlrnum(villa) != rnum){
995 fprintf(stderr, "%s: %s: invalid\n", progname, name);
996 vlclose(villa);
997 return 1;
998 }
999 printfflush("ok\n");
1000 printfflush("Scanning and checking ... ");
1001 i = 0;
1002 for(vlcurlast(villa); (kbuf = vlcurkey(villa, &ksiz)) != NULL; vlcurprev(villa)){
1003 if(vlvnum(villa, kbuf, ksiz) < 1 || !(vbuf = vlcurval(villa, NULL))){
1004 pdperror(name);
1005 free(kbuf);
1006 vlclose(villa);
1007 return 1;
1008 }
1009 free(vbuf);
1010 free(kbuf);
1011 i++;
1012 }
1013 if(i != vlrnum(villa)){
1014 fprintf(stderr, "%s: %s: invalid\n", progname, name);
1015 vlclose(villa);
1016 return 1;
1017 }
1018 printfflush("ok\n");
1019 printfflush("Closing the database ... ");
1020 if(!vlclose(villa)){
1021 pdperror(name);
1022 return 1;
1023 }
1024 printfflush("ok\n");
1025 printfflush("Creating a database with VL_CMPLEX ... ");
1026 omode = VL_OWRITER | VL_OCREAT | VL_OTRUNC | cmode;
1027 if(!(villa = vlopen(name, omode, VL_CMPLEX))){
1028 pdperror(name);
1029 return 1;
1030 }
1031 printfflush("ok\n");
1032 printfflush("Setting tuning parameters with 5, 6, 16, 16 ... ");
1033 vlsettuning(villa, 5, 6, 16, 16);
1034 printfflush("ok\n");
1035 printfflush("Adding 3 * 3 records with VL_DDUP ... ");
1036 for(i = 0; i < 3; i++){
1037 for(j = 0; j < 3; j++){
1038 len = sprintf(buf, "%08d", j);
1039 if(!vlput(villa, buf, len, buf, -1, VL_DDUP)){
1040 pdperror(name);
1041 vlclose(villa);
1042 return 1;
1043 }
1044 }
1045 }
1046 printfflush("ok\n");
1047 printfflush("Inserting records with the cursor ... ");
1048 if(!vlcurjump(villa, "00000001", -1, VL_JFORWARD) ||
1049 !vlcurput(villa, "first", -1, VL_CPAFTER) || !vlcurput(villa, "second", -1, VL_CPAFTER) ||
1050 !vlcurnext(villa) ||
1051 !vlcurput(villa, "third", -1, VL_CPAFTER) ||
1052 strcmp(vlcurvalcache(villa, NULL), "third") ||
1053 !vlcurput(villa, "fourth", -1, VL_CPCURRENT) ||
1054 strcmp(vlcurvalcache(villa, NULL), "fourth") ||
1055 !vlcurjump(villa, "00000001", -1, VL_JFORWARD) ||
1056 strcmp(vlcurvalcache(villa, NULL), "00000001") ||
1057 !vlcurput(villa, "one", -1, VL_CPBEFORE) || !vlcurput(villa, "two", -1, VL_CPBEFORE) ||
1058 !vlcurput(villa, "three", -1, VL_CPBEFORE) || !vlcurput(villa, "five", -1, VL_CPBEFORE) ||
1059 !vlcurnext(villa) ||
1060 !vlcurput(villa, "four", -1, VL_CPBEFORE) ||
1061 strcmp(vlcurvalcache(villa, NULL), "four") ||
1062 !vlcurjump(villa, "00000001*", -1, VL_JBACKWARD) ||
1063 strcmp(vlcurvalcache(villa, NULL), "00000001") ||
1064 !vlcurput(villa, "omega", -1, VL_CPAFTER) ||
1065 strcmp(vlcurkeycache(villa, NULL), "00000001") ||
1066 strcmp(vlcurvalcache(villa, NULL), "omega") ||
1067 !vlcurjump(villa, "00000000*", -1, VL_JFORWARD) ||
1068 !vlcurput(villa, "alpha", -1, VL_CPBEFORE) ||
1069 strcmp(vlcurvalcache(villa, NULL), "alpha") ||
1070 !vlcurprev(villa) ||
1071 strcmp(vlcurkeycache(villa, NULL), "00000000") ||
1072 strcmp(vlcurvalcache(villa, NULL), "00000000") ||
1073 !vlcurput(villa, "before", -1, VL_CPAFTER) ||
1074 strcmp(vlcurvalcache(villa, NULL), "before") ||
1075 !vlcurjump(villa, "00000001*", -1, VL_JFORWARD) ||
1076 !vlcurput(villa, "after", -1, VL_CPBEFORE) ||
1077 strcmp(vlcurvalcache(villa, NULL), "after") ||
1078 !vlcurfirst(villa) ||
1079 strcmp(vlcurvalcache(villa, NULL), "00000000") ||
1080 !vlcurput(villa, "top", -1, VL_CPBEFORE) ||
1081 strcmp(vlcurvalcache(villa, NULL), "top") ||
1082 !vlcurlast(villa) ||
1083 !vlcurput(villa, "bottom", -1, VL_CPAFTER) ||
1084 strcmp(vlcurvalcache(villa, NULL), "bottom")){
1085 fprintf(stderr, "%s: %s: invalid\n", progname, name);
1086 vlclose(villa);
1087 return 1;
1088 }
1089 printfflush("ok\n");
1090 printfflush("Deleting records with the cursor ... ");
1091 if(!vlcurjump(villa, "00000000*", -1, VL_JBACKWARD) ||
1092 strcmp(vlcurvalcache(villa, NULL), "before") ||
1093 !vlcurout(villa) ||
1094 strcmp(vlcurvalcache(villa, NULL), "alpha") ||
1095 !vlcurout(villa) ||
1096 strcmp(vlcurvalcache(villa, NULL), "five") ||
1097 !vlcurfirst(villa) || !vlcurnext(villa) ||
1098 !vlcurout(villa) || !vlcurout(villa) || !vlcurout(villa) ||
1099 strcmp(vlcurvalcache(villa, NULL), "five") ||
1100 !vlcurprev(villa) ||
1101 strcmp(vlcurvalcache(villa, NULL), "top") ||
1102 !vlcurout(villa) ||
1103 strcmp(vlcurvalcache(villa, NULL), "five") ||
1104 !vlcurjump(villa, "00000002", -1, VL_JBACKWARD) ||
1105 strcmp(vlcurvalcache(villa, NULL), "bottom") ||
1106 !vlcurout(villa) ||
1107 !vlcurjump(villa, "00000001", -1, VL_JBACKWARD) ||
1108 !vlcurout(villa) ||
1109 !vlcurout(villa) || !vlcurout(villa) || !vlcurout(villa) ||
1110 strcmp(vlcurkeycache(villa, NULL), "00000002") ||
1111 strcmp(vlcurvalcache(villa, NULL), "00000002") ||
1112 !vlcurout(villa) || vlcurout(villa) ||
1113 !vlcurfirst(villa) ||
1114 strcmp(vlcurvalcache(villa, NULL), "five")){
1115 fprintf(stderr, "%s: %s: invalid\n", progname, name);
1116 vlclose(villa);
1117 return 1;
1118 }
1119 vlcurfirst(villa);
1120 while(vlcurout(villa)){
1121 free(vlcurval(villa, NULL));
1122 }
1123 if(vlrnum(villa) != 0){
1124 printf("%d\n", vlrnum(villa));
1125 fprintf(stderr, "%s: %s: invalid\n", progname, name);
1126 vlclose(villa);
1127 return 1;
1128 }
1129 for(i = 0; i < 1000; i++){
1130 len = sprintf(buf, "%08d", i);
1131 if(!vlput(villa, buf, len, buf, -1, VL_DKEEP)){
1132 pdperror(name);
1133 vlclose(villa);
1134 return 1;
1135 }
1136 }
1137 for(i = 200; i < 800; i++){
1138 len = sprintf(buf, "%08d", i);
1139 if(!vlout(villa, buf, len)){
1140 pdperror(name);
1141 vlclose(villa);
1142 return 1;
1143 }
1144 }
1145 vlcurfirst(villa);
1146 while(vlcurout(villa)){
1147 free(vlcurval(villa, NULL));
1148 }
1149 if(vlrnum(villa) != 0){
1150 printf("%d\n", vlrnum(villa));
1151 fprintf(stderr, "%s: %s: invalid\n", progname, name);
1152 vlclose(villa);
1153 return 1;
1154 }
1155 printfflush("ok\n");
1156 printfflush("Adding 3 * 100 records with VL_DDUP ... ");
1157 for(i = 1; i <= 100; i++){
1158 len = sprintf(buf, "%08d", i);
1159 for(j = 0; j < 3; j++){
1160 if(!vlput(villa, buf, len, buf, len, VL_DDUP)){
1161 pdperror(name);
1162 vlclose(villa);
1163 return 1;
1164 }
1165 }
1166 }
1167 printfflush("ok\n");
1168 printfflush("Closing the database ... ");
1169 if(!vlclose(villa)){
1170 pdperror(name);
1171 return 1;
1172 }
1173 printfflush("ok\n");
1174 printfflush("Opening the database as a reader ... ");
1175 if(!(villa = vlopen(name, VL_OREADER, VL_CMPLEX))){
1176 pdperror(name);
1177 return 1;
1178 }
1179 printfflush("ok\n");
1180 printfflush("Opening multiple cursors ... ");
1181 mulcurs = cbmalloc(sizeof(VLMULCUR *) * 8);
1182 for(i = 0; i < 8; i++){
1183 if(!(mulcurs[i] = vlmulcuropen(villa))){
1184 pdperror(name);
1185 vlclose(villa);
1186 return 1;
1187 }
1188 }
1189 printfflush("ok\n");
1190 printfflush("Scanning multiple cursors ... ");
1191 for(i = 0; i < 8; i++){
1192 if(i % 2 == 0){
1193 vlmulcurfirst(mulcurs[i]);
1194 } else {
1195 vlmulcurlast(mulcurs[i]);
1196 }
1197 }
1198 for(i = 0; i < 300; i++){
1199 for(j = 0; j < 8; j++){
1200 if(j % 2 == 0){
1201 if(!(vbuf = vlmulcurkey(mulcurs[j], &vsiz))){
1202 pdperror(name);
1203 vlclose(villa);
1204 return 1;
1205 }
1206 free(vbuf);
1207 vlmulcurnext(mulcurs[j]);
1208 } else {
1209 if(!(vbuf = vlmulcurval(mulcurs[j], &vsiz))){
1210 pdperror(name);
1211 vlclose(villa);
1212 return 1;
1213 }
1214 free(vbuf);
1215 vlmulcurprev(mulcurs[j]);
1216 }
1217 }
1218 }
1219 printfflush("ok\n");
1220 printfflush("Closing multiple cursors ... ");
1221 for(i = 0; i < 8; i++){
1222 vlmulcurclose(mulcurs[i]);
1223 }
1224 free(mulcurs);
1225 printfflush("ok\n");
1226 printfflush("Closing the database ... ");
1227 if(!vlclose(villa)){
1228 pdperror(name);
1229 return 1;
1230 }
1231 printfflush("ok\n");
1232 printfflush("all ok\n\n");
1233 return 0;
1234 }
1235
1236
1237 /* perform wicked command */
dowicked(const char * name,int rnum,int cb,int cmode)1238 int dowicked(const char *name, int rnum, int cb, int cmode){
1239 VILLA *villa;
1240 CBMAP *map;
1241 int i, j, omode, len, err, ksiz, vsiz, tran, mksiz, mvsiz, rsiz;
1242 const char *mkbuf, *mvbuf;
1243 char buf[32], *kbuf, *vbuf;
1244 CBLIST *list;
1245 printfflush("<Wicked Writing Test>\n name=%s rnum=%d\n\n", name, rnum);
1246 omode = VL_OWRITER | VL_OCREAT | VL_OTRUNC | cmode;
1247 if(!(villa = vlopen(name, omode, VL_CMPLEX))){
1248 pdperror(name);
1249 return 1;
1250 }
1251 err = FALSE;
1252 tran = FALSE;
1253 vlsettuning(villa, 5, 10, 64, 64);
1254 map = NULL;
1255 if(cb) map = cbmapopen();
1256 for(i = 1; i <= rnum; i++){
1257 len = sprintf(buf, "%08d", myrand() % rnum + 1);
1258 switch(cb ? (myrand() % 5) : myrand() % 16){
1259 case 0:
1260 putchar('O');
1261 if(!vlput(villa, buf, len, buf, len, VL_DOVER)) err = TRUE;
1262 if(map) cbmapput(map, buf, len, buf, len, TRUE);
1263 break;
1264 case 1:
1265 putchar('K');
1266 if(!vlput(villa, buf, len, buf, len, VL_DKEEP) && dpecode != DP_EKEEP) err = TRUE;
1267 if(map) cbmapput(map, buf, len, buf, len, FALSE);
1268 break;
1269 case 2:
1270 putchar('C');
1271 if(!vlput(villa, buf, len, buf, len, VL_DCAT)) err = TRUE;
1272 if(map) cbmapputcat(map, buf, len, buf, len);
1273 break;
1274 case 3:
1275 putchar('D');
1276 if(!vlout(villa, buf, len) && dpecode != DP_ENOITEM) err = TRUE;
1277 if(map) cbmapout(map, buf, len);
1278 break;
1279 case 4:
1280 putchar('G');
1281 if((vbuf = vlget(villa, buf, len, NULL)) != NULL){
1282 free(vbuf);
1283 } else if(dpecode != DP_ENOITEM){
1284 err = TRUE;
1285 }
1286 break;
1287 case 5:
1288 putchar('V');
1289 if(vlvsiz(villa, buf, len) < 0 && dpecode != DP_ENOITEM) err = TRUE;
1290 if(!vlvnum(villa, buf, len) && dpecode != DP_ENOITEM) err = TRUE;
1291 break;
1292 case 6:
1293 putchar('X');
1294 list = cblistopen();
1295 cblistpush(list, buf, len);
1296 cblistpush(list, buf, len);
1297 if(!vlputlist(villa, buf, len, list)) err = TRUE;
1298 cblistclose(list);
1299 break;
1300 case 7:
1301 putchar('Y');
1302 if(!vloutlist(villa, buf, len) && dpecode != DP_ENOITEM) err = TRUE;
1303 break;
1304 case 8:
1305 putchar('Z');
1306 if((list = vlgetlist(villa, buf, len)) != NULL){
1307 cblistclose(list);
1308 } else if(dpecode != DP_ENOITEM){
1309 err = TRUE;
1310 }
1311 if((vbuf = vlgetcat(villa, buf, len, NULL)) != NULL){
1312 free(vbuf);
1313 } else if(dpecode != DP_ENOITEM){
1314 err = TRUE;
1315 }
1316 break;
1317 case 9:
1318 putchar('Q');
1319 if(vlcurjump(villa, buf, len, VL_JFORWARD)){
1320 for(j = 0; j < 3 && (kbuf = vlcurkey(villa, &ksiz)); j++){
1321 if(VL_CMPLEX(buf, len, kbuf, ksiz) > 0) err = TRUE;
1322 if(strcmp(vlcurkeycache(villa, NULL), kbuf)) err = TRUE;
1323 if((vbuf = vlcurval(villa, &vsiz)) != NULL){
1324 if(strcmp(vlcurvalcache(villa, NULL), vbuf)) err = TRUE;
1325 free(vbuf);
1326 } else {
1327 err = TRUE;
1328 }
1329 free(kbuf);
1330 if(!vlcurnext(villa) && dpecode != DP_ENOITEM) err = TRUE;
1331 }
1332 } else {
1333 if(dpecode != DP_ENOITEM) err = TRUE;
1334 }
1335 break;
1336 case 10:
1337 putchar('W');
1338 if(vlcurjump(villa, buf, len, VL_JBACKWARD)){
1339 for(j = 0; j < 3 && (kbuf = vlcurkey(villa, &ksiz)); j++){
1340 if(VL_CMPLEX(buf, len, kbuf, ksiz) < 0) err = TRUE;
1341 if(strcmp(vlcurkeycache(villa, NULL), kbuf)) err = TRUE;
1342 if((vbuf = vlcurval(villa, &vsiz)) != NULL){
1343 if(strcmp(vlcurvalcache(villa, NULL), vbuf)) err = TRUE;
1344 free(vbuf);
1345 } else {
1346 err = TRUE;
1347 }
1348 free(kbuf);
1349 if(!vlcurprev(villa) && dpecode != DP_ENOITEM) err = TRUE;
1350 }
1351 } else {
1352 if(dpecode != DP_ENOITEM) err = TRUE;
1353 }
1354 break;
1355 case 11:
1356 putchar('L');
1357 if(myrand() % 3 == 0 &&
1358 !vlcurjump(villa, buf, len, i % 3 == 0 ? VL_JFORWARD : VL_JBACKWARD) &&
1359 dpecode != DP_ENOITEM) err = TRUE;
1360 for(j = myrand() % 5; j >= 0; j--){
1361 switch(myrand() % 6){
1362 case 0:
1363 if(!vlcurput(villa, buf, len, VL_CPAFTER) && dpecode != DP_ENOITEM) err = TRUE;
1364 break;
1365 case 1:
1366 if(!vlcurput(villa, buf, len, VL_CPBEFORE) && dpecode != DP_ENOITEM) err = TRUE;
1367 break;
1368 case 2:
1369 if(!vlcurput(villa, buf, len, VL_CPCURRENT) && dpecode != DP_ENOITEM) err = TRUE;
1370 break;
1371 default:
1372 if(!vlcurout(villa)){
1373 if(dpecode != DP_ENOITEM) err = TRUE;
1374 break;
1375 }
1376 break;
1377 }
1378 }
1379 break;
1380 case 12:
1381 if(tran ? myrand() % 32 != 0 : myrand() % 1024 != 0){
1382 putchar('N');
1383 break;
1384 }
1385 putchar('T');
1386 if(tran){
1387 if(myrand() % 5 == 0){
1388 if(!vltranabort(villa)) err = TRUE;
1389 } else {
1390 if(!vltrancommit(villa)) err = TRUE;
1391 }
1392 tran = FALSE;
1393 } else {
1394 if(!vltranbegin(villa)) err = TRUE;
1395 tran = TRUE;
1396 }
1397 break;
1398 default:
1399 putchar('P');
1400 if(!vlput(villa, buf, len, buf, len, myrand() % 3 == 0 ? VL_DDUPR : VL_DDUP)) err = TRUE;
1401 break;
1402 }
1403 if(i % 50 == 0) printfflush(" (%08d)\n", i);
1404 if(err){
1405 pdperror(name);
1406 break;
1407 }
1408 }
1409 if(tran){
1410 if(!vltranabort(villa)) err = TRUE;
1411 }
1412 if(!vloptimize(villa)){
1413 pdperror(name);
1414 err = TRUE;
1415 }
1416 if((rnum = vlrnum(villa)) == -1){
1417 pdperror(name);
1418 err = TRUE;
1419 }
1420 if(!vlcurfirst(villa)){
1421 pdperror(name);
1422 err = TRUE;
1423 }
1424 i = 0;
1425 do {
1426 kbuf = NULL;
1427 vbuf = NULL;
1428 if(!(kbuf = vlcurkey(villa, &ksiz)) || !(vbuf = vlcurval(villa, &vsiz)) ||
1429 ksiz != 8 || vsiz % 8 != 0 || vlvnum(villa, kbuf, ksiz) < 1){
1430 pdperror(name);
1431 free(kbuf);
1432 free(vbuf);
1433 err = TRUE;
1434 break;
1435 }
1436 free(kbuf);
1437 free(vbuf);
1438 i++;
1439 } while(vlcurnext(villa));
1440 if(i != rnum){
1441 fprintf(stderr, "%s: %s: invalid cursor\n", progname, name);
1442 err = TRUE;
1443 }
1444 if(dpecode != DP_ENOITEM){
1445 pdperror(name);
1446 err = TRUE;
1447 }
1448 if(!vlcurlast(villa)){
1449 pdperror(name);
1450 err = TRUE;
1451 }
1452 i = 0;
1453 do {
1454 kbuf = NULL;
1455 vbuf = NULL;
1456 if(!(kbuf = vlcurkey(villa, &ksiz)) || !(vbuf = vlcurval(villa, &vsiz)) ||
1457 ksiz != 8 || vsiz % 8 != 0 || vlvnum(villa, kbuf, ksiz) < 1){
1458 pdperror(name);
1459 free(kbuf);
1460 free(vbuf);
1461 err = TRUE;
1462 break;
1463 }
1464 free(kbuf);
1465 free(vbuf);
1466 i++;
1467 } while(vlcurprev(villa));
1468 if(i != rnum){
1469 fprintf(stderr, "%s: %s: invalid cursor\n", progname, name);
1470 err = TRUE;
1471 }
1472 if(dpecode != DP_ENOITEM){
1473 pdperror(name);
1474 err = TRUE;
1475 }
1476 if(map){
1477 printfflush("Matching records ... ");
1478 cbmapiterinit(map);
1479 while((mkbuf = cbmapiternext(map, &mksiz)) != NULL){
1480 mvbuf = cbmapget(map, mkbuf, mksiz, &mvsiz);
1481 if(!(vbuf = vlget(villa, mkbuf, mksiz, &rsiz))){
1482 pdperror(name);
1483 err = TRUE;
1484 break;
1485 }
1486 if(rsiz != mvsiz || memcmp(vbuf, mvbuf, rsiz)){
1487 fprintf(stderr, "%s: %s: unmatched record\n", progname, name);
1488 free(vbuf);
1489 err = TRUE;
1490 break;
1491 }
1492 free(vbuf);
1493 }
1494 cbmapclose(map);
1495 if(!err) printfflush("ok\n");
1496 }
1497 if(!vlclose(villa)){
1498 pdperror(name);
1499 return 1;
1500 }
1501 if(!err) printfflush("ok\n\n");
1502 return err ? 1 : 0;
1503 }
1504
1505
1506
1507 /* END OF FILE */
1508