1#include <stdio.h>
2#include <string.h>
3#ifndef VMS
4#include <sys/types.h>
5#endif
6#if defined(SUN)
7#include <unistd.h>
8#endif
9#include "dss.h"
10#include "dsstypes.h"
11
12#include <math.h>
13#ifdef ADHOC
14#include "adhoc.h"
15extern adhoc_t adhocs[];
16#endif /* ADHOC */
17#include "rng64.h"
18
19#define LEAP_ADJ(yr, mnth) ((LEAP(yr) && (mnth) >= 2) ? 1 : 0)
20#define JDAY_BASE 8035 /* start from 1/1/70 a la unix */
21#define JMNTH_BASE (-70 * 12) /* start from 1/1/70 a la unix */
22#define JDAY(date) ((date)-STARTDATE + JDAY_BASE + 1)
23#define PART_SUPP_BRIDGE(tgt, p, s) \
24 { \
25 DSS_HUGE tot_scnt = tdefs[SUPP].base * scale; \
26 tgt = (p + s * (tot_scnt / SUPP_PER_PART + (long)((p - 1) / tot_scnt))) % tot_scnt + 1; \
27 }
28#define V_STR(avg, sd, tgt) a_rnd((int)(avg * V_STR_LOW), (int)(avg * V_STR_HGH), sd, tgt)
29#define TEXT(avg, sd, tgt) dbg_text(tgt, (int)(avg * V_STR_LOW), (int)(avg * V_STR_HGH), sd)
30static void gen_phone PROTO((DSS_HUGE ind, char *target, long seed));
31
32DSS_HUGE
33rpb_routine(DSS_HUGE p) {
34 DSS_HUGE price;
35
36 price = 90000;
37 price += (p / 10) % 20001; /* limit contribution to $200 */
38 price += (p % 1000) * 100;
39
40 return (price);
41}
42
43static void gen_phone(DSS_HUGE ind, char *target, long seed) {
44 DSS_HUGE acode, exchg, number;
45
46 RANDOM(acode, 100, 999, seed);
47 RANDOM(exchg, 100, 999, seed);
48 RANDOM(number, 1000, 9999, seed);
49
50 sprintf(target, "%02d", (int)(10 + (ind % NATIONS_MAX)));
51 sprintf(target + 3, "%03d", (int)acode);
52 sprintf(target + 7, "%03d", (int)exchg);
53 sprintf(target + 11, "%04d", (int)number);
54 target[2] = target[6] = target[10] = '-';
55
56 return;
57}
58
59long mk_cust(DSS_HUGE n_cust, customer_t *c) {
60 DSS_HUGE i;
61 static int bInit = 0;
62 static char szFormat[100];
63
64 if (!bInit) {
65 sprintf(szFormat, C_NAME_FMT, 9, HUGE_FORMAT + 1);
66 bInit = 1;
67 }
68 c->custkey = n_cust;
69 sprintf(c->name, szFormat, C_NAME_TAG, n_cust);
70 V_STR(C_ADDR_LEN, C_ADDR_SD, c->address);
71 c->alen = (int)strlen(c->address);
72 RANDOM(i, 0, (nations.count - 1), C_NTRG_SD);
73 c->nation_code = i;
74 gen_phone(i, c->phone, (long)C_PHNE_SD);
75 RANDOM(c->acctbal, C_ABAL_MIN, C_ABAL_MAX, C_ABAL_SD);
76 pick_str(&c_mseg_set, C_MSEG_SD, c->mktsegment);
77 TEXT(C_CMNT_LEN, C_CMNT_SD, c->comment);
78 c->clen = (int)strlen(c->comment);
79
80 return (0);
81}
82
83/*
84 * generate the numbered order and its associated lineitems
85 */
86void mk_sparse(DSS_HUGE i, DSS_HUGE *ok, long seq) {
87 long low_bits;
88
89 *ok = i;
90 low_bits = (long)(i & ((1 << SPARSE_KEEP) - 1));
91 *ok = *ok >> SPARSE_KEEP;
92 *ok = *ok << SPARSE_BITS;
93 *ok += seq;
94 *ok = *ok << SPARSE_KEEP;
95 *ok += low_bits;
96
97 return;
98}
99
100long mk_order(DSS_HUGE index, order_t *o, long upd_num) {
101 DSS_HUGE lcnt;
102 DSS_HUGE rprice;
103 long ocnt;
104 DSS_HUGE tmp_date;
105 DSS_HUGE s_date;
106 DSS_HUGE r_date;
107 DSS_HUGE c_date;
108 DSS_HUGE clk_num;
109 DSS_HUGE supp_num;
110 static char **asc_date = NULL;
111 char tmp_str[2];
112 char **mk_ascdate PROTO((void));
113 int delta = 1;
114 static int bInit = 0;
115 static char szFormat[100];
116
117 if (!bInit) {
118 sprintf(szFormat, O_CLRK_FMT, 9, HUGE_FORMAT + 1);
119 bInit = 1;
120 }
121 if (asc_date == NULL)
122 asc_date = mk_ascdate();
123 mk_sparse(index, &o->okey, (upd_num == 0) ? 0 : 1 + upd_num / (10000 / UPD_PCT));
124 if (scale >= 30000)
125 RANDOM64(o->custkey, O_CKEY_MIN, O_CKEY_MAX, O_CKEY_SD);
126 else
127 RANDOM(o->custkey, O_CKEY_MIN, O_CKEY_MAX, O_CKEY_SD);
128 while (o->custkey % CUST_MORTALITY == 0) {
129 o->custkey += delta;
130 o->custkey = MIN(o->custkey, O_CKEY_MAX);
131 delta *= -1;
132 }
133
134 RANDOM(tmp_date, O_ODATE_MIN, O_ODATE_MAX, O_ODATE_SD);
135 strcpy(o->odate, asc_date[tmp_date - STARTDATE]);
136
137 pick_str(&o_priority_set, O_PRIO_SD, o->opriority);
138 RANDOM(clk_num, 1, MAX((scale * O_CLRK_SCL), O_CLRK_SCL), O_CLRK_SD);
139 sprintf(o->clerk, szFormat, O_CLRK_TAG, clk_num);
140 TEXT(O_CMNT_LEN, O_CMNT_SD, o->comment);
141 o->clen = (int)strlen(o->comment);
142#ifdef DEBUG
143 if (o->clen > O_CMNT_MAX)
144 fprintf(stderr, "comment error: O%d\n", index);
145#endif /* DEBUG */
146 o->spriority = 0;
147
148 o->totalprice = 0;
149 o->orderstatus = 'O';
150 ocnt = 0;
151
152 RANDOM(o->lines, O_LCNT_MIN, O_LCNT_MAX, O_LCNT_SD);
153 for (lcnt = 0; lcnt < o->lines; lcnt++) {
154 o->l[lcnt].okey = o->okey;
155 ;
156 o->l[lcnt].lcnt = lcnt + 1;
157 RANDOM(o->l[lcnt].quantity, L_QTY_MIN, L_QTY_MAX, L_QTY_SD);
158 RANDOM(o->l[lcnt].discount, L_DCNT_MIN, L_DCNT_MAX, L_DCNT_SD);
159 RANDOM(o->l[lcnt].tax, L_TAX_MIN, L_TAX_MAX, L_TAX_SD);
160 pick_str(&l_instruct_set, L_SHIP_SD, o->l[lcnt].shipinstruct);
161 pick_str(&l_smode_set, L_SMODE_SD, o->l[lcnt].shipmode);
162 TEXT(L_CMNT_LEN, L_CMNT_SD, o->l[lcnt].comment);
163 o->l[lcnt].clen = (int)strlen(o->l[lcnt].comment);
164 if (scale >= 30000)
165 RANDOM64(o->l[lcnt].partkey, L_PKEY_MIN, L_PKEY_MAX, L_PKEY_SD);
166 else
167 RANDOM(o->l[lcnt].partkey, L_PKEY_MIN, L_PKEY_MAX, L_PKEY_SD);
168 rprice = rpb_routine(o->l[lcnt].partkey);
169 RANDOM(supp_num, 0, 3, L_SKEY_SD);
170 PART_SUPP_BRIDGE(o->l[lcnt].suppkey, o->l[lcnt].partkey, supp_num);
171 o->l[lcnt].eprice = rprice * o->l[lcnt].quantity;
172
173 o->totalprice += ((o->l[lcnt].eprice * ((long)100 - o->l[lcnt].discount)) / (long)PENNIES) *
174 ((long)100 + o->l[lcnt].tax) / (long)PENNIES;
175
176 RANDOM(s_date, L_SDTE_MIN, L_SDTE_MAX, L_SDTE_SD);
177 s_date += tmp_date;
178 RANDOM(c_date, L_CDTE_MIN, L_CDTE_MAX, L_CDTE_SD);
179 c_date += tmp_date;
180 RANDOM(r_date, L_RDTE_MIN, L_RDTE_MAX, L_RDTE_SD);
181 r_date += s_date;
182
183 strcpy(o->l[lcnt].sdate, asc_date[s_date - STARTDATE]);
184 strcpy(o->l[lcnt].cdate, asc_date[c_date - STARTDATE]);
185 strcpy(o->l[lcnt].rdate, asc_date[r_date - STARTDATE]);
186
187 if (julian(r_date) <= CURRENTDATE) {
188 pick_str(&l_rflag_set, L_RFLG_SD, tmp_str);
189 o->l[lcnt].rflag[0] = *tmp_str;
190 } else
191 o->l[lcnt].rflag[0] = 'N';
192
193 if (julian(s_date) <= CURRENTDATE) {
194 ocnt++;
195 o->l[lcnt].lstatus[0] = 'F';
196 } else
197 o->l[lcnt].lstatus[0] = 'O';
198 }
199
200 if (ocnt > 0)
201 o->orderstatus = 'P';
202 if (ocnt == o->lines)
203 o->orderstatus = 'F';
204
205 return (0);
206}
207
208long mk_part(DSS_HUGE index, part_t *p) {
209 DSS_HUGE temp;
210 long snum;
211 DSS_HUGE brnd;
212 static int bInit = 0;
213 static char szFormat[100];
214 static char szBrandFormat[100];
215
216 if (!bInit) {
217 sprintf(szFormat, P_MFG_FMT, 1, HUGE_FORMAT + 1);
218 sprintf(szBrandFormat, P_BRND_FMT, 2, HUGE_FORMAT + 1);
219 bInit = 1;
220 }
221 p->partkey = index;
222 agg_str(&colors, (long)P_NAME_SCL, (long)P_NAME_SD, p->name);
223 RANDOM(temp, P_MFG_MIN, P_MFG_MAX, P_MFG_SD);
224 sprintf(p->mfgr, szFormat, P_MFG_TAG, temp);
225 RANDOM(brnd, P_BRND_MIN, P_BRND_MAX, P_BRND_SD);
226 sprintf(p->brand, szBrandFormat, P_BRND_TAG, (temp * 10 + brnd));
227 p->tlen = pick_str(&p_types_set, P_TYPE_SD, p->type);
228 p->tlen = (int)strlen(p_types_set.list[p->tlen].text);
229 RANDOM(p->size, P_SIZE_MIN, P_SIZE_MAX, P_SIZE_SD);
230 pick_str(&p_cntr_set, P_CNTR_SD, p->container);
231 p->retailprice = rpb_routine(index);
232 TEXT(P_CMNT_LEN, P_CMNT_SD, p->comment);
233 p->clen = (int)strlen(p->comment);
234
235 for (snum = 0; snum < SUPP_PER_PART; snum++) {
236 p->s[snum].partkey = p->partkey;
237 PART_SUPP_BRIDGE(p->s[snum].suppkey, index, snum);
238 RANDOM(p->s[snum].qty, PS_QTY_MIN, PS_QTY_MAX, PS_QTY_SD);
239 RANDOM(p->s[snum].scost, PS_SCST_MIN, PS_SCST_MAX, PS_SCST_SD);
240 TEXT(PS_CMNT_LEN, PS_CMNT_SD, p->s[snum].comment);
241 p->s[snum].clen = (int)strlen(p->s[snum].comment);
242 }
243 return (0);
244}
245
246long mk_supp(DSS_HUGE index, supplier_t *s) {
247 DSS_HUGE i, bad_press, noise, offset, type;
248 static int bInit = 0;
249 static char szFormat[100];
250
251 if (!bInit) {
252 sprintf(szFormat, S_NAME_FMT, 9, HUGE_FORMAT + 1);
253 bInit = 1;
254 }
255 s->suppkey = index;
256 sprintf(s->name, szFormat, S_NAME_TAG, index);
257 V_STR(S_ADDR_LEN, S_ADDR_SD, s->address);
258 s->alen = (int)strlen(s->address);
259 RANDOM(i, 0, nations.count - 1, S_NTRG_SD);
260 s->nation_code = i;
261 gen_phone(i, s->phone, S_PHNE_SD);
262 RANDOM(s->acctbal, S_ABAL_MIN, S_ABAL_MAX, S_ABAL_SD);
263
264 TEXT(S_CMNT_LEN, S_CMNT_SD, s->comment);
265 s->clen = (int)strlen(s->comment);
266 /*
267 * these calls should really move inside the if stmt below, but this
268 * will simplify seedless parallel load
269 */
270 RANDOM(bad_press, 1, 10000, BBB_CMNT_SD);
271 RANDOM(type, 0, 100, BBB_TYPE_SD);
272 RANDOM(noise, 0, (s->clen - BBB_CMNT_LEN), BBB_JNK_SD);
273 RANDOM(offset, 0, (s->clen - (BBB_CMNT_LEN + noise)), BBB_OFFSET_SD);
274 if (bad_press <= S_CMNT_BBB) {
275 type = (type < BBB_DEADBEATS) ? 0 : 1;
276 memcpy(s->comment + offset, BBB_BASE, BBB_BASE_LEN);
277 if (type == 0)
278 memcpy(s->comment + BBB_BASE_LEN + offset + noise, BBB_COMPLAIN, BBB_TYPE_LEN);
279 else
280 memcpy(s->comment + BBB_BASE_LEN + offset + noise, BBB_COMMEND, BBB_TYPE_LEN);
281 }
282 return (0);
283}
284
285struct {
286 char *mdes;
287 long days;
288 long dcnt;
289} months[] =
290
291 {{NULL, 0, 0}, {"JAN", 31, 31}, {"FEB", 28, 59}, {"MAR", 31, 90}, {"APR", 30, 120},
292 {"MAY", 31, 151}, {"JUN", 30, 181}, {"JUL", 31, 212}, {"AUG", 31, 243}, {"SEP", 30, 273},
293 {"OCT", 31, 304}, {"NOV", 30, 334}, {"DEC", 31, 365}};
294
295long mk_time(DSS_HUGE index, dss_time_t *t) {
296 long m = 0;
297 long y;
298 long d;
299
300 t->timekey = index + JDAY_BASE;
301 y = julian(index + STARTDATE - 1) / 1000;
302 d = julian(index + STARTDATE - 1) % 1000;
303 while (d > months[m].dcnt + LEAP_ADJ(y, m))
304 m++;
305 PR_DATE(t->alpha, y, m, d - months[m - 1].dcnt - ((LEAP(y) && m > 2) ? 1 : 0));
306 t->year = 1900 + y;
307 t->month = m + 12 * y + JMNTH_BASE;
308 t->week = (d + T_START_DAY - 1) / 7 + 1;
309 t->day = d - months[m - 1].dcnt - LEAP_ADJ(y, m - 1);
310
311 return (0);
312}
313
314int mk_nation(DSS_HUGE index, code_t *c) {
315 c->code = index - 1;
316 c->text = nations.list[index - 1].text;
317 c->join = nations.list[index - 1].weight;
318 TEXT(N_CMNT_LEN, N_CMNT_SD, c->comment);
319 c->clen = (int)strlen(c->comment);
320 return (0);
321}
322
323int mk_region(DSS_HUGE index, code_t *c) {
324
325 c->code = index - 1;
326 c->text = regions.list[index - 1].text;
327 c->join = 0; /* for completeness */
328 TEXT(R_CMNT_LEN, R_CMNT_SD, c->comment);
329 c->clen = (int)strlen(c->comment);
330 return (0);
331}
332