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 | */ |
109 | void usage (void); |
110 | void kill_load (void); |
111 | int pload (int tbl); |
112 | void gen_tbl (int tnum, DSS_HUGE start, DSS_HUGE count, long upd_num); |
113 | int pr_drange (int tbl, DSS_HUGE min, DSS_HUGE cnt, long num); |
114 | int set_files (int t, int pload); |
115 | int partial (int, int); |
116 | |
117 | |
118 | extern int optind, opterr; |
119 | extern char *optarg; |
120 | DSS_HUGE rowcnt = 0, minrow = 0; |
121 | long upd_num = 0; |
122 | double flt_scale; |
123 | #if (defined(WIN32)&&!defined(_POSIX_)) |
124 | char *spawn_args[25]; |
125 | #endif |
126 | #ifdef RNG_TEST |
127 | extern seed_t Seed[]; |
128 | #endif |
129 | static 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 | */ |
156 | int pr_cust (customer_t * c, int mode); |
157 | int pr_line (order_t * o, int mode); |
158 | int pr_order (order_t * o, int mode); |
159 | int pr_part (part_t * p, int mode); |
160 | int pr_psupp (part_t * p, int mode); |
161 | int pr_supp (supplier_t * s, int mode); |
162 | int pr_order_line (order_t * o, int mode); |
163 | int pr_part_psupp (part_t * p, int mode); |
164 | int pr_nation (code_t * c, int mode); |
165 | int pr_region (code_t * c, int mode); |
166 | |
167 | /* |
168 | * seed generation functions; used with '-O s' option |
169 | */ |
170 | long sd_cust (int child, DSS_HUGE skip_count); |
171 | long sd_line (int child, DSS_HUGE skip_count); |
172 | long sd_order (int child, DSS_HUGE skip_count); |
173 | long sd_part (int child, DSS_HUGE skip_count); |
174 | long sd_psupp (int child, DSS_HUGE skip_count); |
175 | long sd_supp (int child, DSS_HUGE skip_count); |
176 | long sd_order_line (int child, DSS_HUGE skip_count); |
177 | long sd_part_psupp (int child, DSS_HUGE skip_count); |
178 | |
179 | tdef 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 | */ |
206 | int |
207 | set_files (int i, int pload) |
208 | { |
209 | char line[80], *new_name; |
210 | |
211 | if (table & (1 << i)) |
212 | child_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 | */ |
247 | void |
248 | load_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" , ®ions); |
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 | */ |
283 | void |
284 | gen_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 | |
377 | void |
378 | usage (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 | */ |
420 | int |
421 | partial (int tbl, int s) |
422 | { |
423 | DSS_HUGE rowcnt; |
424 | DSS_HUGE ; |
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 | |
447 | void |
448 | process_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 | |
607 | void 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 | */ |
661 | int |
662 | main (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 | |