1 | /* |
2 | * $Id: build.c,v 1.5 2009/06/28 14:01:08 jms Exp $ |
3 | * |
4 | * Revision History =================== $Log: build.c,v $ |
5 | * Revision History =================== Revision 1.5 2009/06/28 14:01:08 jms |
6 | * Revision History =================== bug fix for DOP |
7 | * Revision History =================== Revision 1.4 |
8 | * 2005/10/28 02:56:22 jms add platform-specific printf formats to allow for |
9 | * DSS_HUGE data type |
10 | * |
11 | * Revision 1.3 2005/10/14 23:16:54 jms fix for answer set compliance |
12 | * |
13 | * Revision 1.2 2005/01/03 20:08:58 jms change line terminations |
14 | * |
15 | * Revision 1.1.1.1 2004/11/24 23:31:46 jms re-establish external server |
16 | * |
17 | * Revision 1.3 2004/04/07 20:17:29 jms bug #58 (join fails between |
18 | * order/lineitem) |
19 | * |
20 | * Revision 1.2 2004/01/22 05:49:29 jms AIX porting (AIX 5.1) |
21 | * |
22 | * Revision 1.1.1.1 2003/08/08 21:35:26 jms recreation after CVS crash |
23 | * |
24 | * Revision 1.3 2003/08/08 21:35:26 jms first integration of rng64 for |
25 | * o_custkey and l_partkey |
26 | * |
27 | * Revision 1.2 2003/08/07 17:58:34 jms Convery RNG to 64bit space as |
28 | * preparation for new large scale RNG |
29 | * |
30 | * Revision 1.1.1.1 2003/04/03 18:54:21 jms initial checkin |
31 | * |
32 | * |
33 | */ |
34 | /* stuff related to the customer table */ |
35 | #include <stdio.h> |
36 | #include <string.h> |
37 | #ifndef VMS |
38 | #include <sys/types.h> |
39 | #endif |
40 | #if defined(SUN) |
41 | #include <unistd.h> |
42 | #endif |
43 | #include <math.h> |
44 | |
45 | #include "dss.h" |
46 | #include "dsstypes.h" |
47 | #ifdef ADHOC |
48 | #include "adhoc.h" |
49 | extern adhoc_t adhocs[]; |
50 | #endif /* ADHOC */ |
51 | #include "rng64.h" |
52 | |
53 | #define LEAP_ADJ(yr, mnth) \ |
54 | ((LEAP(yr) && (mnth) >= 2) ? 1 : 0) |
55 | #define JDAY_BASE 8035 /* start from 1/1/70 a la unix */ |
56 | #define JMNTH_BASE (-70 * 12) /* start from 1/1/70 a la unix */ |
57 | #define JDAY(date) ((date) - STARTDATE + JDAY_BASE + 1) |
58 | #define PART_SUPP_BRIDGE(tgt, p, s) \ |
59 | { \ |
60 | DSS_HUGE tot_scnt = tdefs[SUPP].base * scale; \ |
61 | tgt = (p + s * (tot_scnt / SUPP_PER_PART + \ |
62 | (long) ((p - 1) / tot_scnt))) % tot_scnt + 1; \ |
63 | } |
64 | #define V_STR(avg, sd, tgt) a_rnd((int)(avg * V_STR_LOW),(int)(avg * V_STR_HGH), sd, tgt) |
65 | #define TEXT(avg, sd, tgt) dbg_text(tgt, (int)(avg * V_STR_LOW),(int)(avg * V_STR_HGH), sd) |
66 | static void gen_phone PROTO((DSS_HUGE ind, char *target, long seed)); |
67 | |
68 | DSS_HUGE |
69 | rpb_routine(DSS_HUGE p) |
70 | { |
71 | DSS_HUGE price; |
72 | |
73 | price = 90000; |
74 | price += (p / 10) % 20001; /* limit contribution to $200 */ |
75 | price += (p % 1000) * 100; |
76 | |
77 | return (price); |
78 | } |
79 | |
80 | static void |
81 | gen_phone(DSS_HUGE ind, char *target, long seed) |
82 | { |
83 | DSS_HUGE acode, exchg, number; |
84 | |
85 | RANDOM(acode, 100, 999, seed); |
86 | RANDOM(exchg, 100, 999, seed); |
87 | RANDOM(number, 1000, 9999, seed); |
88 | |
89 | sprintf(target, "%02d" , (int) (10 + (ind % NATIONS_MAX))); |
90 | sprintf(target + 3, "%03d" , (int) acode); |
91 | sprintf(target + 7, "%03d" , (int) exchg); |
92 | sprintf(target + 11, "%04d" , (int) number); |
93 | target[2] = target[6] = target[10] = '-'; |
94 | |
95 | return; |
96 | } |
97 | |
98 | |
99 | |
100 | long |
101 | mk_cust(DSS_HUGE n_cust, customer_t * c) |
102 | { |
103 | DSS_HUGE i; |
104 | static int bInit = 0; |
105 | static char szFormat[100]; |
106 | |
107 | if (!bInit) |
108 | { |
109 | sprintf(szFormat, C_NAME_FMT, 9, HUGE_FORMAT + 1); |
110 | bInit = 1; |
111 | } |
112 | c->custkey = n_cust; |
113 | sprintf(c->name, szFormat, C_NAME_TAG, n_cust); |
114 | V_STR(C_ADDR_LEN, C_ADDR_SD, c->address); |
115 | c->alen = (int)strlen(c->address); |
116 | RANDOM(i, 0, (nations.count - 1), C_NTRG_SD); |
117 | c->nation_code = i; |
118 | gen_phone(i, c->phone, (long) C_PHNE_SD); |
119 | RANDOM(c->acctbal, C_ABAL_MIN, C_ABAL_MAX, C_ABAL_SD); |
120 | pick_str(&c_mseg_set, C_MSEG_SD, c->mktsegment); |
121 | TEXT(C_CMNT_LEN, C_CMNT_SD, c->comment); |
122 | c->clen = (int)strlen(c->comment); |
123 | |
124 | return (0); |
125 | } |
126 | |
127 | |
128 | /* |
129 | * generate the numbered order and its associated lineitems |
130 | */ |
131 | void |
132 | mk_sparse(DSS_HUGE i, DSS_HUGE * ok, long seq) |
133 | { |
134 | long low_bits; |
135 | |
136 | *ok = i; |
137 | low_bits = (long) (i & ((1 << SPARSE_KEEP) - 1)); |
138 | *ok = *ok >> SPARSE_KEEP; |
139 | *ok = *ok << SPARSE_BITS; |
140 | *ok += seq; |
141 | *ok = *ok << SPARSE_KEEP; |
142 | *ok += low_bits; |
143 | |
144 | |
145 | return; |
146 | } |
147 | |
148 | long |
149 | mk_order(DSS_HUGE index, order_t * o, long upd_num) |
150 | { |
151 | DSS_HUGE lcnt; |
152 | DSS_HUGE rprice; |
153 | long ocnt; |
154 | DSS_HUGE tmp_date; |
155 | DSS_HUGE s_date; |
156 | DSS_HUGE r_date; |
157 | DSS_HUGE c_date; |
158 | DSS_HUGE clk_num; |
159 | DSS_HUGE supp_num; |
160 | static char **asc_date = NULL; |
161 | char tmp_str[2]; |
162 | char **mk_ascdate PROTO((void)); |
163 | int delta = 1; |
164 | static int bInit = 0; |
165 | static char szFormat[100]; |
166 | |
167 | if (!bInit) |
168 | { |
169 | sprintf(szFormat, O_CLRK_FMT, 9, HUGE_FORMAT + 1); |
170 | bInit = 1; |
171 | } |
172 | if (asc_date == NULL) |
173 | asc_date = mk_ascdate(); |
174 | mk_sparse(index, &o->okey, |
175 | (upd_num == 0) ? 0 : 1 + upd_num / (10000 / UPD_PCT)); |
176 | if (scale >= 30000) |
177 | RANDOM64(o->custkey, O_CKEY_MIN, O_CKEY_MAX, O_CKEY_SD); |
178 | else |
179 | RANDOM(o->custkey, O_CKEY_MIN, O_CKEY_MAX, O_CKEY_SD); |
180 | while (o->custkey % CUST_MORTALITY == 0) |
181 | { |
182 | o->custkey += delta; |
183 | o->custkey = MIN(o->custkey, O_CKEY_MAX); |
184 | delta *= -1; |
185 | } |
186 | |
187 | |
188 | RANDOM(tmp_date, O_ODATE_MIN, O_ODATE_MAX, O_ODATE_SD); |
189 | strcpy(o->odate, asc_date[tmp_date - STARTDATE]); |
190 | |
191 | pick_str(&o_priority_set, O_PRIO_SD, o->opriority); |
192 | RANDOM(clk_num, 1, MAX((scale * O_CLRK_SCL), O_CLRK_SCL), O_CLRK_SD); |
193 | sprintf(o->clerk, szFormat, O_CLRK_TAG, clk_num); |
194 | TEXT(O_CMNT_LEN, O_CMNT_SD, o->comment); |
195 | o->clen = (int)strlen(o->comment); |
196 | #ifdef DEBUG |
197 | if (o->clen > O_CMNT_MAX) |
198 | fprintf(stderr, "comment error: O%d\n" , index); |
199 | #endif /* DEBUG */ |
200 | o->spriority = 0; |
201 | |
202 | o->totalprice = 0; |
203 | o->orderstatus = 'O'; |
204 | ocnt = 0; |
205 | |
206 | RANDOM(o->lines, O_LCNT_MIN, O_LCNT_MAX, O_LCNT_SD); |
207 | for (lcnt = 0; lcnt < o->lines; lcnt++) |
208 | { |
209 | o->l[lcnt].okey = o->okey;; |
210 | o->l[lcnt].lcnt = lcnt + 1; |
211 | RANDOM(o->l[lcnt].quantity, L_QTY_MIN, L_QTY_MAX, L_QTY_SD); |
212 | RANDOM(o->l[lcnt].discount, L_DCNT_MIN, L_DCNT_MAX, L_DCNT_SD); |
213 | RANDOM(o->l[lcnt].tax, L_TAX_MIN, L_TAX_MAX, L_TAX_SD); |
214 | pick_str(&l_instruct_set, L_SHIP_SD, o->l[lcnt].shipinstruct); |
215 | pick_str(&l_smode_set, L_SMODE_SD, o->l[lcnt].shipmode); |
216 | TEXT(L_CMNT_LEN, L_CMNT_SD, o->l[lcnt].comment); |
217 | o->l[lcnt].clen = (int)strlen(o->l[lcnt].comment); |
218 | if (scale >= 30000) |
219 | RANDOM64(o->l[lcnt].partkey, L_PKEY_MIN, L_PKEY_MAX, L_PKEY_SD); |
220 | else |
221 | RANDOM(o->l[lcnt].partkey, L_PKEY_MIN, L_PKEY_MAX, L_PKEY_SD); |
222 | rprice = rpb_routine(o->l[lcnt].partkey); |
223 | RANDOM(supp_num, 0, 3, L_SKEY_SD); |
224 | PART_SUPP_BRIDGE(o->l[lcnt].suppkey, o->l[lcnt].partkey, supp_num); |
225 | o->l[lcnt].eprice = rprice * o->l[lcnt].quantity; |
226 | |
227 | o->totalprice += |
228 | ((o->l[lcnt].eprice * |
229 | ((long) 100 - o->l[lcnt].discount)) / (long) PENNIES) * |
230 | ((long) 100 + o->l[lcnt].tax) |
231 | / (long) PENNIES; |
232 | |
233 | RANDOM(s_date, L_SDTE_MIN, L_SDTE_MAX, L_SDTE_SD); |
234 | s_date += tmp_date; |
235 | RANDOM(c_date, L_CDTE_MIN, L_CDTE_MAX, L_CDTE_SD); |
236 | c_date += tmp_date; |
237 | RANDOM(r_date, L_RDTE_MIN, L_RDTE_MAX, L_RDTE_SD); |
238 | r_date += s_date; |
239 | |
240 | |
241 | strcpy(o->l[lcnt].sdate, asc_date[s_date - STARTDATE]); |
242 | strcpy(o->l[lcnt].cdate, asc_date[c_date - STARTDATE]); |
243 | strcpy(o->l[lcnt].rdate, asc_date[r_date - STARTDATE]); |
244 | |
245 | |
246 | if (julian(r_date) <= CURRENTDATE) |
247 | { |
248 | pick_str(&l_rflag_set, L_RFLG_SD, tmp_str); |
249 | o->l[lcnt].rflag[0] = *tmp_str; |
250 | } |
251 | else |
252 | o->l[lcnt].rflag[0] = 'N'; |
253 | |
254 | if (julian(s_date) <= CURRENTDATE) |
255 | { |
256 | ocnt++; |
257 | o->l[lcnt].lstatus[0] = 'F'; |
258 | } |
259 | else |
260 | o->l[lcnt].lstatus[0] = 'O'; |
261 | } |
262 | |
263 | if (ocnt > 0) |
264 | o->orderstatus = 'P'; |
265 | if (ocnt == o->lines) |
266 | o->orderstatus = 'F'; |
267 | |
268 | return (0); |
269 | } |
270 | |
271 | long |
272 | mk_part(DSS_HUGE index, part_t * p) |
273 | { |
274 | DSS_HUGE temp; |
275 | long snum; |
276 | DSS_HUGE brnd; |
277 | static int bInit = 0; |
278 | static char szFormat[100]; |
279 | static char szBrandFormat[100]; |
280 | |
281 | if (!bInit) |
282 | { |
283 | sprintf(szFormat, P_MFG_FMT, 1, HUGE_FORMAT + 1); |
284 | sprintf(szBrandFormat, P_BRND_FMT, 2, HUGE_FORMAT + 1); |
285 | bInit = 1; |
286 | } |
287 | p->partkey = index; |
288 | agg_str(&colors, (long) P_NAME_SCL, (long) P_NAME_SD, p->name); |
289 | RANDOM(temp, P_MFG_MIN, P_MFG_MAX, P_MFG_SD); |
290 | sprintf(p->mfgr, szFormat, P_MFG_TAG, temp); |
291 | RANDOM(brnd, P_BRND_MIN, P_BRND_MAX, P_BRND_SD); |
292 | sprintf(p->brand, szBrandFormat, P_BRND_TAG, (temp * 10 + brnd)); |
293 | p->tlen = pick_str(&p_types_set, P_TYPE_SD, p->type); |
294 | p->tlen = (int)strlen(p_types_set.list[p->tlen].text); |
295 | RANDOM(p->size, P_SIZE_MIN, P_SIZE_MAX, P_SIZE_SD); |
296 | pick_str(&p_cntr_set, P_CNTR_SD, p->container); |
297 | p->retailprice = rpb_routine(index); |
298 | TEXT(P_CMNT_LEN, P_CMNT_SD, p->comment); |
299 | p->clen = (int)strlen(p->comment); |
300 | |
301 | for (snum = 0; snum < SUPP_PER_PART; snum++) |
302 | { |
303 | p->s[snum].partkey = p->partkey; |
304 | PART_SUPP_BRIDGE(p->s[snum].suppkey, index, snum); |
305 | RANDOM(p->s[snum].qty, PS_QTY_MIN, PS_QTY_MAX, PS_QTY_SD); |
306 | RANDOM(p->s[snum].scost, PS_SCST_MIN, PS_SCST_MAX, PS_SCST_SD); |
307 | TEXT(PS_CMNT_LEN, PS_CMNT_SD, p->s[snum].comment); |
308 | p->s[snum].clen = (int)strlen(p->s[snum].comment); |
309 | } |
310 | return (0); |
311 | } |
312 | |
313 | long |
314 | mk_supp(DSS_HUGE index, supplier_t * s) |
315 | { |
316 | DSS_HUGE i, bad_press, noise, offset, type; |
317 | static int bInit = 0; |
318 | static char szFormat[100]; |
319 | |
320 | if (!bInit) |
321 | { |
322 | sprintf(szFormat, S_NAME_FMT, 9, HUGE_FORMAT + 1); |
323 | bInit = 1; |
324 | } |
325 | s->suppkey = index; |
326 | sprintf(s->name, szFormat, S_NAME_TAG, index); |
327 | V_STR(S_ADDR_LEN, S_ADDR_SD, s->address); |
328 | s->alen = (int)strlen(s->address); |
329 | RANDOM(i, 0, nations.count - 1, S_NTRG_SD); |
330 | s->nation_code = i; |
331 | gen_phone(i, s->phone, S_PHNE_SD); |
332 | RANDOM(s->acctbal, S_ABAL_MIN, S_ABAL_MAX, S_ABAL_SD); |
333 | |
334 | TEXT(S_CMNT_LEN, S_CMNT_SD, s->comment); |
335 | s->clen = (int)strlen(s->comment); |
336 | /* |
337 | * these calls should really move inside the if stmt below, but this |
338 | * will simplify seedless parallel load |
339 | */ |
340 | RANDOM(bad_press, 1, 10000, BBB_CMNT_SD); |
341 | RANDOM(type, 0, 100, BBB_TYPE_SD); |
342 | RANDOM(noise, 0, (s->clen - BBB_CMNT_LEN), BBB_JNK_SD); |
343 | RANDOM(offset, 0, (s->clen - (BBB_CMNT_LEN + noise)), |
344 | BBB_OFFSET_SD); |
345 | if (bad_press <= S_CMNT_BBB) |
346 | { |
347 | type = (type < BBB_DEADBEATS) ? 0 : 1; |
348 | memcpy(s->comment + offset, BBB_BASE, BBB_BASE_LEN); |
349 | if (type == 0) |
350 | memcpy(s->comment + BBB_BASE_LEN + offset + noise, |
351 | BBB_COMPLAIN, BBB_TYPE_LEN); |
352 | else |
353 | memcpy(s->comment + BBB_BASE_LEN + offset + noise, |
354 | BBB_COMMEND, BBB_TYPE_LEN); |
355 | } |
356 | return (0); |
357 | } |
358 | |
359 | struct |
360 | { |
361 | char *mdes; |
362 | long days; |
363 | long dcnt; |
364 | } months[] = |
365 | |
366 | { |
367 | { |
368 | NULL, 0, 0 |
369 | }, |
370 | { |
371 | "JAN" , 31, 31 |
372 | }, |
373 | { |
374 | "FEB" , 28, 59 |
375 | }, |
376 | { |
377 | "MAR" , 31, 90 |
378 | }, |
379 | { |
380 | "APR" , 30, 120 |
381 | }, |
382 | { |
383 | "MAY" , 31, 151 |
384 | }, |
385 | { |
386 | "JUN" , 30, 181 |
387 | }, |
388 | { |
389 | "JUL" , 31, 212 |
390 | }, |
391 | { |
392 | "AUG" , 31, 243 |
393 | }, |
394 | { |
395 | "SEP" , 30, 273 |
396 | }, |
397 | { |
398 | "OCT" , 31, 304 |
399 | }, |
400 | { |
401 | "NOV" , 30, 334 |
402 | }, |
403 | { |
404 | "DEC" , 31, 365 |
405 | } |
406 | }; |
407 | |
408 | long |
409 | mk_time(DSS_HUGE index, dss_time_t * t) |
410 | { |
411 | long m = 0; |
412 | long y; |
413 | long d; |
414 | |
415 | t->timekey = index + JDAY_BASE; |
416 | y = julian(index + STARTDATE - 1) / 1000; |
417 | d = julian(index + STARTDATE - 1) % 1000; |
418 | while (d > months[m].dcnt + LEAP_ADJ(y, m)) |
419 | m++; |
420 | PR_DATE(t->alpha, y, m, |
421 | d - months[m - 1].dcnt - ((LEAP(y) && m > 2) ? 1 : 0)); |
422 | t->year = 1900 + y; |
423 | t->month = m + 12 * y + JMNTH_BASE; |
424 | t->week = (d + T_START_DAY - 1) / 7 + 1; |
425 | t->day = d - months[m - 1].dcnt - LEAP_ADJ(y, m - 1); |
426 | |
427 | return (0); |
428 | } |
429 | |
430 | int |
431 | mk_nation(DSS_HUGE index, code_t * c) |
432 | { |
433 | c->code = index - 1; |
434 | c->text = nations.list[index - 1].text; |
435 | c->join = nations.list[index - 1].weight; |
436 | TEXT(N_CMNT_LEN, N_CMNT_SD, c->comment); |
437 | c->clen = (int)strlen(c->comment); |
438 | return (0); |
439 | } |
440 | |
441 | int |
442 | mk_region(DSS_HUGE index, code_t * c) |
443 | { |
444 | |
445 | c->code = index - 1; |
446 | c->text = regions.list[index - 1].text; |
447 | c->join = 0; /* for completeness */ |
448 | TEXT(R_CMNT_LEN, R_CMNT_SD, c->comment); |
449 | c->clen = (int)strlen(c->comment); |
450 | return (0); |
451 | } |
452 | |