1/*
2* $Id: driver.c,v 1.7 2008/09/24 22:35:21 jms Exp $
3*
4* Revision History
5* ===================
6* $Log: driver.c,v $
7* Revision 1.7 2008/09/24 22:35:21 jms
8* remove build number header
9*
10* Revision 1.6 2008/09/24 22:30:29 jms
11* remove build number from default header
12*
13* Revision 1.5 2008/03/21 17:38:39 jms
14* changes for 2.6.3
15*
16* Revision 1.4 2006/04/26 23:01:10 jms
17* address update generation problems
18*
19* Revision 1.3 2005/10/28 02:54:35 jms
20* add release.h changes
21*
22* Revision 1.2 2005/01/03 20:08:58 jms
23* change line terminations
24*
25* Revision 1.1.1.1 2004/11/24 23:31:46 jms
26* re-establish external server
27*
28* Revision 1.5 2004/04/07 20:17:29 jms
29* bug #58 (join fails between order/lineitem)
30*
31* Revision 1.4 2004/02/18 16:26:49 jms
32* 32/64 bit changes for overflow handling needed additional changes when ported back to windows
33*
34* Revision 1.3 2004/01/22 05:49:29 jms
35* AIX porting (AIX 5.1)
36*
37* Revision 1.2 2004/01/22 03:54:12 jms
38* 64 bit support changes for customer address
39*
40* Revision 1.1.1.1 2003/08/08 21:50:33 jms
41* recreation after CVS crash
42*
43* Revision 1.3 2003/08/08 21:35:26 jms
44* first integration of rng64 for o_custkey and l_partkey
45*
46* Revision 1.2 2003/08/07 17:58:34 jms
47* Convery RNG to 64bit space as preparation for new large scale RNG
48*
49* Revision 1.1.1.1 2003/04/03 18:54:21 jms
50* initial checkin
51*
52*
53*/
54/* main driver for dss banchmark */
55
56#define DECLARER /* EXTERN references get defined here */
57#define NO_FUNC (int (*) ()) NULL /* to clean up tdefs */
58#define NO_LFUNC (long (*) ()) NULL /* to clean up tdefs */
59
60#include "config.h"
61#include "release.h"
62#include <stdlib.h>
63#if (defined(_POSIX_)||!defined(WIN32)) /* Change for Windows NT */
64#include <unistd.h>
65#include <sys/wait.h>
66#endif /* WIN32 */
67#include <stdio.h> /* */
68#include <limits.h>
69#include <math.h>
70#include <ctype.h>
71#include <signal.h>
72#include <string.h>
73#include <errno.h>
74#ifdef HP
75#include <strings.h>
76#endif
77#if (defined(WIN32)&&!defined(_POSIX_))
78#include <process.h>
79#pragma warning(disable:4201)
80#pragma warning(disable:4214)
81#pragma warning(disable:4514)
82#define WIN32_LEAN_AND_MEAN
83#define NOATOM
84#define NOGDICAPMASKS
85#define NOMETAFILE
86#define NOMINMAX
87#define NOMSG
88#define NOOPENFILE
89#define NORASTEROPS
90#define NOSCROLL
91#define NOSOUND
92#define NOSYSMETRICS
93#define NOTEXTMETRIC
94#define NOWH
95#define NOCOMM
96#define NOKANJI
97#define NOMCX
98#include <windows.h>
99#pragma warning(default:4201)
100#pragma warning(default:4214)
101#endif
102
103#include "dss.h"
104#include "dsstypes.h"
105
106/*
107* Function prototypes
108*/
109void usage (void);
110void kill_load (void);
111int pload (int tbl);
112void gen_tbl (int tnum, DSS_HUGE start, DSS_HUGE count, long upd_num);
113int pr_drange (int tbl, DSS_HUGE min, DSS_HUGE cnt, long num);
114int set_files (int t, int pload);
115int partial (int, int);
116
117
118extern int optind, opterr;
119extern char *optarg;
120DSS_HUGE rowcnt = 0, minrow = 0;
121long upd_num = 0;
122double flt_scale;
123#if (defined(WIN32)&&!defined(_POSIX_))
124char *spawn_args[25];
125#endif
126#ifdef RNG_TEST
127extern seed_t Seed[];
128#endif
129static int bTableSet = 0;
130
131
132/*
133* general table descriptions. See dss.h for details on structure
134* NOTE: tables with no scaling info are scaled according to
135* another table
136*
137*
138* the following is based on the tdef structure defined in dss.h as:
139* typedef struct
140* {
141* char *name; -- name of the table;
142* flat file output in <name>.tbl
143* long base; -- base scale rowcount of table;
144* 0 if derived
145* int (*loader) (); -- function to present output
146* long (*gen_seed) (); -- functions to seed the RNG
147* int child; -- non-zero if there is an associated detail table
148* unsigned long vtotal; -- "checksum" total
149* } tdef;
150*
151*/
152
153/*
154* flat file print functions; used with -F(lat) option
155*/
156int pr_cust (customer_t * c, int mode);
157int pr_line (order_t * o, int mode);
158int pr_order (order_t * o, int mode);
159int pr_part (part_t * p, int mode);
160int pr_psupp (part_t * p, int mode);
161int pr_supp (supplier_t * s, int mode);
162int pr_order_line (order_t * o, int mode);
163int pr_part_psupp (part_t * p, int mode);
164int pr_nation (code_t * c, int mode);
165int pr_region (code_t * c, int mode);
166
167/*
168* seed generation functions; used with '-O s' option
169*/
170long sd_cust (int child, DSS_HUGE skip_count);
171long sd_line (int child, DSS_HUGE skip_count);
172long sd_order (int child, DSS_HUGE skip_count);
173long sd_part (int child, DSS_HUGE skip_count);
174long sd_psupp (int child, DSS_HUGE skip_count);
175long sd_supp (int child, DSS_HUGE skip_count);
176long sd_order_line (int child, DSS_HUGE skip_count);
177long sd_part_psupp (int child, DSS_HUGE skip_count);
178
179tdef tdefs[] =
180{
181 {"part.tbl", "part table", 200000,
182 pr_part, sd_part, PSUPP, 0},
183 {"partsupp.tbl", "partsupplier table", 200000,
184 pr_psupp, sd_psupp, NONE, 0},
185 {"supplier.tbl", "suppliers table", 10000,
186 pr_supp, sd_supp, NONE, 0},
187 {"customer.tbl", "customers table", 150000,
188 pr_cust, sd_cust, NONE, 0},
189 {"orders.tbl", "order table", 150000,
190 pr_order, sd_order, LINE, 0},
191 {"lineitem.tbl", "lineitem table", 150000,
192 pr_line, sd_line, NONE, 0},
193 {"orders.tbl", "orders/lineitem tables", 150000,
194 pr_order_line, sd_order, LINE, 0},
195 {"part.tbl", "part/partsupplier tables", 200000,
196 pr_part_psupp, sd_part, PSUPP, 0},
197 {"nation.tbl", "nation table", NATIONS_MAX,
198 pr_nation, NO_LFUNC, NONE, 0},
199 {"region.tbl", "region table", NATIONS_MAX,
200 pr_region, NO_LFUNC, NONE, 0},
201};
202
203/*
204* re-set default output file names
205*/
206int
207set_files (int i, int pload)
208{
209 char line[80], *new_name;
210
211 if (table & (1 << i))
212child_table:
213 {
214 if (pload != -1)
215 sprintf (line, "%s.%d", tdefs[i].name, pload);
216 else
217 {
218 printf ("Enter new destination for %s data: ",
219 tdefs[i].name);
220 if (fgets (line, sizeof (line), stdin) == NULL)
221 return (-1);;
222 if ((new_name = strchr (line, '\n')) != NULL)
223 *new_name = '\0';
224 if ((int)strlen (line) == 0)
225 return (0);
226 }
227 new_name = (char *) malloc ((int)strlen (line) + 1);
228 MALLOC_CHECK (new_name);
229 strcpy (new_name, line);
230 tdefs[i].name = new_name;
231 if (tdefs[i].child != NONE)
232 {
233 i = tdefs[i].child;
234 tdefs[i].child = NONE;
235 goto child_table;
236 }
237 }
238
239 return (0);
240}
241
242
243
244/*
245* read the distributions needed in the benchamrk
246*/
247void
248load_dists (void)
249{
250 read_dist (env_config (DIST_TAG, DIST_DFLT), "p_cntr", &p_cntr_set);
251 read_dist (env_config (DIST_TAG, DIST_DFLT), "colors", &colors);
252 read_dist (env_config (DIST_TAG, DIST_DFLT), "p_types", &p_types_set);
253 read_dist (env_config (DIST_TAG, DIST_DFLT), "nations", &nations);
254 read_dist (env_config (DIST_TAG, DIST_DFLT), "regions", &regions);
255 read_dist (env_config (DIST_TAG, DIST_DFLT), "o_oprio",
256 &o_priority_set);
257 read_dist (env_config (DIST_TAG, DIST_DFLT), "instruct",
258 &l_instruct_set);
259 read_dist (env_config (DIST_TAG, DIST_DFLT), "smode", &l_smode_set);
260 read_dist (env_config (DIST_TAG, DIST_DFLT), "category",
261 &l_category_set);
262 read_dist (env_config (DIST_TAG, DIST_DFLT), "rflag", &l_rflag_set);
263 read_dist (env_config (DIST_TAG, DIST_DFLT), "msegmnt", &c_mseg_set);
264
265 /* load the distributions that contain text generation */
266 read_dist (env_config (DIST_TAG, DIST_DFLT), "nouns", &nouns);
267 read_dist (env_config (DIST_TAG, DIST_DFLT), "verbs", &verbs);
268 read_dist (env_config (DIST_TAG, DIST_DFLT), "adjectives", &adjectives);
269 read_dist (env_config (DIST_TAG, DIST_DFLT), "adverbs", &adverbs);
270 read_dist (env_config (DIST_TAG, DIST_DFLT), "auxillaries", &auxillaries);
271 read_dist (env_config (DIST_TAG, DIST_DFLT), "terminators", &terminators);
272 read_dist (env_config (DIST_TAG, DIST_DFLT), "articles", &articles);
273 read_dist (env_config (DIST_TAG, DIST_DFLT), "prepositions", &prepositions);
274 read_dist (env_config (DIST_TAG, DIST_DFLT), "grammar", &grammar);
275 read_dist (env_config (DIST_TAG, DIST_DFLT), "np", &np);
276 read_dist (env_config (DIST_TAG, DIST_DFLT), "vp", &vp);
277
278}
279
280/*
281* generate a particular table
282*/
283void
284gen_tbl (int tnum, DSS_HUGE start, DSS_HUGE count, long upd_num)
285{
286 static order_t o;
287 supplier_t supp;
288 customer_t cust;
289 part_t part;
290 code_t code;
291 static int completed = 0;
292 DSS_HUGE i;
293
294 DSS_HUGE rows_per_segment=0;
295 DSS_HUGE rows_this_segment=-1;
296 DSS_HUGE residual_rows=0;
297
298 if (insert_segments)
299 {
300 rows_per_segment = count / insert_segments;
301 residual_rows = count - (rows_per_segment * insert_segments);
302 }
303
304 for (i = start; count; count--, i++)
305 {
306 LIFENOISE (1000, i);
307 row_start(tnum);
308
309 switch (tnum)
310 {
311 case LINE:
312 case ORDER:
313 case ORDER_LINE:
314 mk_order (i, &o, upd_num % 10000);
315
316 if (insert_segments && (upd_num > 0))
317 if((upd_num / 10000) < residual_rows)
318 {
319 if((++rows_this_segment) > rows_per_segment)
320 {
321 rows_this_segment=0;
322 upd_num += 10000;
323 }
324 }
325 else
326 {
327 if((++rows_this_segment) >= rows_per_segment)
328 {
329 rows_this_segment=0;
330 upd_num += 10000;
331 }
332 }
333
334 if (set_seeds == 0)
335 tdefs[tnum].loader(&o, upd_num);
336 break;
337 case SUPP:
338 mk_supp (i, &supp);
339 if (set_seeds == 0)
340 tdefs[tnum].loader(&supp, upd_num);
341 break;
342 case CUST:
343 mk_cust (i, &cust);
344 if (set_seeds == 0)
345 tdefs[tnum].loader(&cust, upd_num);
346 break;
347 case PSUPP:
348 case PART:
349 case PART_PSUPP:
350 mk_part (i, &part);
351 if (set_seeds == 0)
352 tdefs[tnum].loader(&part, upd_num);
353 break;
354 case NATION:
355 mk_nation (i, &code);
356 if (set_seeds == 0)
357 tdefs[tnum].loader(&code, 0);
358 break;
359 case REGION:
360 mk_region (i, &code);
361 if (set_seeds == 0)
362 tdefs[tnum].loader(&code, 0);
363 break;
364 }
365 row_stop(tnum);
366 if (set_seeds && (i % tdefs[tnum].base) < 2)
367 {
368 printf("\nSeeds for %s at rowcount %ld\n", tdefs[tnum].comment, i);
369 dump_seeds(tnum);
370 }
371 }
372 completed |= 1 << tnum;
373}
374
375
376
377void
378usage (void)
379{
380 fprintf (stderr, "%s\n%s\n\t%s\n%s %s\n\n",
381 "USAGE:",
382 "dbgen [-{vf}][-T {pcsoPSOL}]",
383 "[-s <scale>][-C <procs>][-S <step>]",
384 "dbgen [-v] [-O m] [-s <scale>]",
385 "[-U <updates>]");
386 fprintf (stderr, "Basic Options\n===========================\n");
387 fprintf (stderr, "-C <n> -- separate data set into <n> chunks (requires -S, default: 1)\n");
388 fprintf (stderr, "-f -- force. Overwrite existing files\n");
389 fprintf (stderr, "-h -- display this message\n");
390 fprintf (stderr, "-q -- enable QUIET mode\n");
391 fprintf (stderr, "-s <n> -- set Scale Factor (SF) to <n> (default: 1) \n");
392 fprintf (stderr, "-S <n> -- build the <n>th step of the data/update set (used with -C or -U)\n");
393 fprintf (stderr, "-U <n> -- generate <n> update sets\n");
394 fprintf (stderr, "-v -- enable VERBOSE mode\n");
395 fprintf (stderr, "\nAdvanced Options\n===========================\n");
396 fprintf (stderr, "-b <s> -- load distributions for <s> (default: dists.dss)\n");
397 fprintf (stderr, "-d <n> -- split deletes between <n> files (requires -U)\n");
398 fprintf (stderr, "-i <n> -- split inserts between <n> files (requires -U)\n");
399 fprintf (stderr, "-T c -- generate cutomers ONLY\n");
400 fprintf (stderr, "-T l -- generate nation/region ONLY\n");
401 fprintf (stderr, "-T L -- generate lineitem ONLY\n");
402 fprintf (stderr, "-T n -- generate nation ONLY\n");
403 fprintf (stderr, "-T o -- generate orders/lineitem ONLY\n");
404 fprintf (stderr, "-T O -- generate orders ONLY\n");
405 fprintf (stderr, "-T p -- generate parts/partsupp ONLY\n");
406 fprintf (stderr, "-T P -- generate parts ONLY\n");
407 fprintf (stderr, "-T r -- generate region ONLY\n");
408 fprintf (stderr, "-T s -- generate suppliers ONLY\n");
409 fprintf (stderr, "-T S -- generate partsupp ONLY\n");
410 fprintf (stderr,
411 "\nTo generate the SF=1 (1GB), validation database population, use:\n");
412 fprintf (stderr, "\tdbgen -vf -s 1\n");
413 fprintf (stderr, "\nTo generate updates for a SF=1 (1GB), use:\n");
414 fprintf (stderr, "\tdbgen -v -U 1 -s 1\n");
415}
416
417/*
418* int partial(int tbl, int s) -- generate the s-th part of the named tables data
419*/
420int
421partial (int tbl, int s)
422{
423 DSS_HUGE rowcnt;
424 DSS_HUGE extra;
425
426 if (verbose > 0)
427 {
428 fprintf (stderr, "\tStarting to load stage %d of %ld for %s...",
429 s, children, tdefs[tbl].comment);
430 }
431
432 set_files (tbl, s);
433
434 rowcnt = set_state(tbl, scale, children, s, &extra);
435
436 if (s == children)
437 gen_tbl (tbl, rowcnt * (s - 1) + 1, rowcnt + extra, upd_num);
438 else
439 gen_tbl (tbl, rowcnt * (s - 1) + 1, rowcnt, upd_num);
440
441 if (verbose > 0)
442 fprintf (stderr, "done.\n");
443
444 return (0);
445}
446
447void
448process_options (int count, char **vector)
449{
450 int option;
451 FILE *pF;
452
453 while ((option = getopt (count, vector,
454 "b:C:d:fi:hO:P:qs:S:T:U:v")) != -1)
455 switch (option)
456 {
457 case 'b': /* load distributions from named file */
458 d_path = (char *)malloc((int)strlen(optarg) + 1);
459 MALLOC_CHECK(d_path);
460 strcpy(d_path, optarg);
461 if ((pF = fopen(d_path, "r")) == NULL)
462 {
463 fprintf(stderr, "ERROR: Invalid argument to -b");
464 exit(-1);
465 }
466 else
467 fclose(pF);
468
469 break;
470 case 'C':
471 children = atoi (optarg);
472 break;
473 case 'd':
474 delete_segments = atoi (optarg);
475 break;
476 case 'f': /* blind overwrites; Force */
477 force = 1;
478 break;
479 case 'i':
480 insert_segments = atoi (optarg);
481 break;
482 case 'q': /* all prompts disabled */
483 verbose = -1;
484 break;
485 case 's': /* scale by Percentage of base rowcount */
486 case 'P': /* for backward compatibility */
487 flt_scale = atof (optarg);
488 if (flt_scale < MIN_SCALE)
489 {
490 int i;
491 int int_scale;
492
493 scale = 1;
494 int_scale = (int)(1000 * flt_scale);
495 for (i = PART; i < REGION; i++)
496 {
497 tdefs[i].base = (DSS_HUGE)(int_scale * tdefs[i].base)/1000;
498 if (tdefs[i].base < 1)
499 tdefs[i].base = 1;
500 }
501 }
502 else
503 scale = (long) flt_scale;
504 if (scale > MAX_SCALE)
505 {
506 fprintf (stderr, "%s %5.0f %s\n\t%s\n\n",
507 "NOTE: Data generation for scale factors >",
508 MAX_SCALE,
509 "GB is still in development,",
510 "and is not yet supported.\n");
511 fprintf (stderr,
512 "Your resulting data set MAY NOT BE COMPLIANT!\n");
513 }
514 break;
515 case 'S': /* generate a particular STEP */
516 step = atoi (optarg);
517 break;
518 case 'U': /* generate flat files for update stream */
519 updates = atoi (optarg);
520 break;
521 case 'v': /* life noises enabled */
522 verbose = 1;
523 break;
524 case 'T': /* generate a specifc table */
525 switch (*optarg)
526 {
527 case 'c': /* generate customer ONLY */
528 table = 1 << CUST;
529 bTableSet = 1;
530 break;
531 case 'L': /* generate lineitems ONLY */
532 table = 1 << LINE;
533 bTableSet = 1;
534 break;
535 case 'l': /* generate code table ONLY */
536 table = 1 << NATION;
537 table |= 1 << REGION;
538 bTableSet = 1;
539 break;
540 case 'n': /* generate nation table ONLY */
541 table = 1 << NATION;
542 bTableSet = 1;
543 break;
544 case 'O': /* generate orders ONLY */
545 table = 1 << ORDER;
546 bTableSet = 1;
547 break;
548 case 'o': /* generate orders/lineitems ONLY */
549 table = 1 << ORDER_LINE;
550 bTableSet = 1;
551 break;
552 case 'P': /* generate part ONLY */
553 table = 1 << PART;
554 bTableSet = 1;
555 break;
556 case 'p': /* generate part/partsupp ONLY */
557 table = 1 << PART_PSUPP;
558 bTableSet = 1;
559 break;
560 case 'r': /* generate region table ONLY */
561 table = 1 << REGION;
562 bTableSet = 1;
563 break;
564 case 'S': /* generate partsupp ONLY */
565 table = 1 << PSUPP;
566 bTableSet = 1;
567 break;
568 case 's': /* generate suppliers ONLY */
569 table = 1 << SUPP;
570 bTableSet = 1;
571 break;
572 default:
573 fprintf (stderr, "Unknown table name %s\n",
574 optarg);
575 usage ();
576 exit (1);
577 }
578 break;
579 case 'O': /* optional actions */
580 switch (tolower (*optarg))
581 {
582 case 's': /* calibrate the RNG usage */
583 set_seeds = 1;
584 break;
585 default:
586 fprintf (stderr, "Unknown option name %s\n",
587 optarg);
588 usage ();
589 exit (1);
590 }
591 break;
592 default:
593 printf ("ERROR: option '%c' unknown.\n",
594 *(vector[optind] + 1));
595 case 'h': /* something unexpected */
596 fprintf (stderr,
597 "%s Population Generator (Version %d.%d.%d build %d)\n",
598 NAME, VERSION, RELEASE, PATCH, BUILD);
599 fprintf (stderr, "Copyright %s %s\n", TPC, C_DATES);
600 usage ();
601 exit (1);
602 }
603
604 return;
605}
606
607void validate_options(void)
608{
609 // DBGenOptions, 3.1
610 if (children != 1)
611 {
612 if (updates != 0)
613 {
614 fprintf(stderr, "ERROR: -C is not valid when generating updates\n");
615 exit(-1);
616 }
617 if (step == -1)
618 {
619 fprintf(stderr, "ERROR: -S must be specified when generating data in multiple chunks\n");
620 exit(-1);
621 }
622 }
623
624 // DBGenOptions, 3.3
625 if (updates == 0)
626 {
627 if ((insert_segments != 0) || (delete_segments != 0))
628 {
629 fprintf(stderr, "ERROR: -d/-i are only valid when generating updates\n");
630 exit(-1);
631 }
632 }
633
634 // DBGenOptions, 3.9
635 if (step != -1)
636 {
637 if ((children == 1) && (updates == 0))
638 {
639 fprintf(stderr, "ERROR: -S is only valid when generating data in multiple chunks or generating updates\n");
640 exit(-1);
641 }
642 }
643
644 // DBGenOptions, 3.10
645 if (bTableSet && (updates != 0))
646 {
647 fprintf(stderr, "ERROR: -T not valid when generating updates\n");
648 exit(-1);
649 }
650
651 return;
652}
653
654
655/*
656* MAIN
657*
658* assumes the existance of getopt() to clean up the command
659* line handling
660*/
661int
662main (int ac, char **av)
663{
664 DSS_HUGE i;
665
666 table = (1 << CUST) |
667 (1 << SUPP) |
668 (1 << NATION) |
669 (1 << REGION) |
670 (1 << PART_PSUPP) |
671 (1 << ORDER_LINE);
672 force = 0;
673 insert_segments=0;
674 delete_segments=0;
675 insert_orders_segment=0;
676 insert_lineitem_segment=0;
677 delete_segment=0;
678 verbose = 0;
679 set_seeds = 0;
680 scale = 1;
681 flt_scale = 1.0;
682 updates = 0;
683 step = -1;
684 tdefs[ORDER].base *=
685 ORDERS_PER_CUST; /* have to do this after init */
686 tdefs[LINE].base *=
687 ORDERS_PER_CUST; /* have to do this after init */
688 tdefs[ORDER_LINE].base *=
689 ORDERS_PER_CUST; /* have to do this after init */
690 children = 1;
691 d_path = NULL;
692
693#ifdef NO_SUPPORT
694 signal (SIGINT, exit);
695#endif /* NO_SUPPORT */
696 process_options (ac, av);
697 validate_options();
698#if (defined(WIN32)&&!defined(_POSIX_))
699 for (i = 0; i < ac; i++)
700 {
701 spawn_args[i] = malloc (((int)strlen (av[i]) + 1) * sizeof (char));
702 MALLOC_CHECK (spawn_args[i]);
703 strcpy (spawn_args[i], av[i]);
704 }
705 spawn_args[ac] = NULL;
706#endif
707
708 if (verbose >= 0)
709 {
710 fprintf (stderr,
711 "%s Population Generator (Version %d.%d.%d)\n",
712 NAME, VERSION, RELEASE, PATCH);
713 fprintf (stderr, "Copyright %s %s\n", TPC, C_DATES);
714 }
715
716 load_dists ();
717#ifdef RNG_TEST
718 for (i=0; i <= MAX_STREAM; i++)
719 Seed[i].nCalls = 0;
720#endif
721 /* have to do this after init */
722 tdefs[NATION].base = nations.count;
723 tdefs[REGION].base = regions.count;
724
725 /*
726 * updates are never parallelized
727 */
728 if (updates)
729 {
730 /*
731 * set RNG to start generating rows beyond SF=scale
732 */
733 set_state (ORDER, scale, 100, 101, &i);
734 rowcnt = (int)(tdefs[ORDER_LINE].base / 10000 * scale * UPD_PCT);
735 if (step > 0)
736 {
737 /*
738 * adjust RNG for any prior update generation
739 */
740 for (i=1; i < step; i++)
741 {
742 sd_order(0, rowcnt);
743 sd_line(0, rowcnt);
744 }
745 upd_num = step - 1;
746 }
747 else
748 upd_num = 0;
749
750 while (upd_num < updates)
751 {
752 if (verbose > 0)
753 fprintf (stderr,
754 "Generating update pair #%ld for %s",
755 upd_num + 1, tdefs[ORDER_LINE].comment);
756 insert_orders_segment=0;
757 insert_lineitem_segment=0;
758 delete_segment=0;
759 minrow = upd_num * rowcnt + 1;
760 gen_tbl (ORDER_LINE, minrow, rowcnt, upd_num + 1);
761 if (verbose > 0)
762 fprintf (stderr, "done.\n");
763 pr_drange (ORDER_LINE, minrow, rowcnt, upd_num + 1);
764 upd_num++;
765 }
766
767 exit (0);
768 }
769
770 /**
771 ** actual data generation section starts here
772 **/
773
774 /*
775 * traverse the tables, invoking the appropriate data generation routine for any to be built
776 */
777 for (i = PART; i <= REGION; i++)
778 if (table & (1 << i))
779 {
780 if (children > 1 && i < NATION)
781 {
782 partial ((int)i, step);
783 }
784 else
785 {
786 minrow = 1;
787 if (i < NATION)
788 rowcnt = tdefs[i].base * scale;
789 else
790 rowcnt = tdefs[i].base;
791 if (verbose > 0)
792 fprintf (stderr, "Generating data for %s", tdefs[i].comment);
793 gen_tbl ((int)i, minrow, rowcnt, upd_num);
794 if (verbose > 0)
795 fprintf (stderr, "done.\n");
796 }
797 }
798
799 return (0);
800}
801