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"
49extern 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)
66static void gen_phone PROTO((DSS_HUGE ind, char *target, long seed));
67
68DSS_HUGE
69rpb_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
80static void
81gen_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
100long
101mk_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 */
131void
132mk_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
148long
149mk_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
271long
272mk_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
313long
314mk_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
359struct
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
408long
409mk_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
430int
431mk_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
441int
442mk_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