1 | /* |
2 | * Legal Notice |
3 | * |
4 | * This document and associated source code (the "Work") is a part of a |
5 | * benchmark specification maintained by the TPC. |
6 | * |
7 | * The TPC reserves all right, title, and interest to the Work as provided |
8 | * under U.S. and international laws, including without limitation all patent |
9 | * and trademark rights therein. |
10 | * |
11 | * No Warranty |
12 | * |
13 | * 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION |
14 | * CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE |
15 | * AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER |
16 | * WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY, |
17 | * INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES, |
18 | * DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR |
19 | * PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF |
20 | * WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE. |
21 | * ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, |
22 | * QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT |
23 | * WITH REGARD TO THE WORK. |
24 | * 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO |
25 | * ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE |
26 | * COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS |
27 | * OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT, |
28 | * INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY, |
29 | * OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT |
30 | * RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD |
31 | * ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. |
32 | * |
33 | * Contributors: |
34 | * Gradient Systems |
35 | */ |
36 | #include "config.h" |
37 | #include "porting.h" |
38 | #include <stdio.h> |
39 | #include <assert.h> |
40 | #include <stdio.h> |
41 | #include "config.h" |
42 | #include "porting.h" |
43 | #include "dist.h" |
44 | #include "constants.h" |
45 | #include "genrand.h" |
46 | #include "columns.h" |
47 | #include "tdefs.h" |
48 | #include "error_msg.h" |
49 | #include "r_params.h" |
50 | #include "tdefs.h" |
51 | #include "tdef_functions.h" |
52 | #include "w_inventory.h" |
53 | #include "scaling.h" |
54 | #include "tpcds.idx.h" |
55 | #include "parallel.h" |
56 | #include "scd.h" |
57 | |
58 | static struct SCALING_T { |
59 | ds_key_t kBaseRowcount; |
60 | ds_key_t kNextInsertValue; |
61 | int nUpdatePercentage; |
62 | ds_key_t kDayRowcount[6]; |
63 | } arRowcount[MAX_TABLE + 1]; |
64 | static int arUpdateDates[6]; |
65 | static int arInventoryUpdateDates[6]; |
66 | |
67 | static int arScaleVolume[9] = {1, 10, 100, 300, 1000, 3000, 10000, 30000, 100000}; |
68 | |
69 | void setUpdateScaling(int table); |
70 | int row_skip(int tbl, ds_key_t count); |
71 | |
72 | /* |
73 | * Routine: |
74 | * Purpose: |
75 | * Algorithm: |
76 | * Data Structures: |
77 | * |
78 | * Params: |
79 | * Returns: |
80 | * Called By: |
81 | * Calls: |
82 | * Assumptions: |
83 | * Side Effects: |
84 | * TODO: None |
85 | */ |
86 | int getScaleSlot(int nTargetGB) { |
87 | int i; |
88 | |
89 | for (i = 0; nTargetGB > arScaleVolume[i]; i++) |
90 | ; |
91 | |
92 | return (i); |
93 | } |
94 | |
95 | /* |
96 | * Routine: LogScale(void) |
97 | * Purpose: use the command line volume target, in GB, to calculate the global |
98 | * rowcount multiplier Algorithm: Data Structures: |
99 | * |
100 | * Params: |
101 | * Returns: |
102 | * Called By: |
103 | * Calls: |
104 | * Assumptions: |
105 | * Side Effects: arRowcounts are set to the appropriate number of rows for the |
106 | * target scale factor |
107 | * TODO: None |
108 | */ |
109 | static ds_key_t LogScale(int nTable, int nTargetGB) { |
110 | int nIndex = 1, nDelta, i; |
111 | float fOffset; |
112 | ds_key_t hgRowcount = 0; |
113 | |
114 | i = getScaleSlot(nTargetGB); |
115 | |
116 | nDelta = dist_weight(NULL, "rowcounts" , nTable + 1, i + 1) - dist_weight(NULL, "rowcounts" , nTable + 1, i); |
117 | fOffset = (float)(nTargetGB - arScaleVolume[i - 1]) / (float)(arScaleVolume[i] - arScaleVolume[i - 1]); |
118 | |
119 | hgRowcount = (int)(fOffset * (float)nDelta); |
120 | hgRowcount += dist_weight(NULL, "rowcounts" , nTable + 1, nIndex); |
121 | |
122 | return (hgRowcount); |
123 | } |
124 | |
125 | /* |
126 | * Routine: StaticScale(void) |
127 | * Purpose: use the command line volume target, in GB, to calculate the global |
128 | * rowcount multiplier Algorithm: Data Structures: |
129 | * |
130 | * Params: |
131 | * Returns: |
132 | * Called By: |
133 | * Calls: |
134 | * Assumptions: |
135 | * Side Effects: arRowcounts are set to the appropriate number of rows for the |
136 | * target scale factor |
137 | * TODO: None |
138 | */ |
139 | static ds_key_t StaticScale(int nTable, int nTargetGB) { |
140 | return (dist_weight(NULL, "rowcounts" , nTable + 1, 1)); |
141 | } |
142 | |
143 | /* |
144 | * Routine: LinearScale(void) |
145 | * Purpose: use the command line volume target, in GB, to calculate the global |
146 | *rowcount multiplier Algorithm: Data Structures: |
147 | * |
148 | * Params: |
149 | * Returns: |
150 | * Called By: |
151 | * Calls: |
152 | * Assumptions: scale factors defined in rowcounts distribution define |
153 | *1/10/100/1000/... GB with sufficient accuracy Side Effects: arRowcounts are |
154 | *set to the appropriate number of rows for the target scale factor |
155 | * TODO: None |
156 | */ |
157 | static ds_key_t LinearScale(int nTable, int nTargetGB) { |
158 | int i; |
159 | ds_key_t hgRowcount = 0; |
160 | |
161 | for (i = 8; i >= 0; i--) /* work from large scales down)*/ |
162 | { |
163 | /* |
164 | * use the defined rowcounts to build up the target GB volume |
165 | */ |
166 | while (nTargetGB >= arScaleVolume[i]) { |
167 | hgRowcount += dist_weight(NULL, "rowcounts" , nTable + 1, i + 1); |
168 | nTargetGB -= arScaleVolume[i]; |
169 | } |
170 | } |
171 | |
172 | return (hgRowcount); |
173 | } |
174 | /* |
175 | * Routine: |
176 | * Purpose: |
177 | * Algorithm: |
178 | * Data Structures: |
179 | * |
180 | * Params: |
181 | * Returns: |
182 | * Called By: |
183 | * Calls: |
184 | * Assumptions: |
185 | * Side Effects: |
186 | * TODO: None |
187 | */ |
188 | ds_key_t getIDCount(int nTable) { |
189 | ds_key_t kRowcount, kUniqueCount; |
190 | tdef *pTdef; |
191 | |
192 | kRowcount = get_rowcount(nTable); |
193 | if (nTable >= PSEUDO_TABLE_START) |
194 | return (kRowcount); |
195 | pTdef = getSimpleTdefsByNumber(nTable); |
196 | if (pTdef->flags & FL_TYPE_2) { |
197 | kUniqueCount = (kRowcount / 6) * 3; |
198 | switch (kRowcount % 6) { |
199 | case 1: |
200 | kUniqueCount += 1; |
201 | break; |
202 | case 2: |
203 | case 3: |
204 | kUniqueCount += 2; |
205 | break; |
206 | case 4: |
207 | case 5: |
208 | kUniqueCount += 3; |
209 | break; |
210 | } |
211 | return (kUniqueCount); |
212 | } else { |
213 | return (kRowcount); |
214 | } |
215 | } |
216 | |
217 | /* |
218 | * Routine: get_rowcount(int table) |
219 | * Purpose: |
220 | * Algorithm: |
221 | * Data Structures: |
222 | * |
223 | * Params: |
224 | * Returns: |
225 | * Called By: |
226 | * Calls: |
227 | * Assumptions: |
228 | * Side Effects: |
229 | * TODO: 20040820 jms Need to address special case scaling in a more general |
230 | * fashion |
231 | */ |
232 | ds_key_t get_rowcount(int table) { |
233 | |
234 | static int bScaleSet = 0, nScale; |
235 | int nTable, nMultiplier, i, nBadScale = 0, nRowcountOffset = 0; |
236 | tdef *pTdef; |
237 | |
238 | if (!bScaleSet) { |
239 | nScale = get_int("SCALE" ); |
240 | if (nScale > 100000) |
241 | ReportErrorNoLine(QERR_BAD_SCALE, NULL, 1); |
242 | |
243 | memset(arRowcount, 0, sizeof(long) * MAX_TABLE); |
244 | for (nTable = CALL_CENTER; nTable <= MAX_TABLE; nTable++) { |
245 | switch (nScale) { |
246 | case 100000: |
247 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 9); |
248 | break; |
249 | case 30000: |
250 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 8); |
251 | break; |
252 | case 10000: |
253 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 7); |
254 | break; |
255 | case 3000: |
256 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 6); |
257 | break; |
258 | case 1000: |
259 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 5); |
260 | break; |
261 | case 300: |
262 | nBadScale = QERR_BAD_SCALE; |
263 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 4); |
264 | break; |
265 | case 100: |
266 | nBadScale = QERR_BAD_SCALE; |
267 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 3); |
268 | break; |
269 | case 10: |
270 | nBadScale = QERR_BAD_SCALE; |
271 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 2); |
272 | break; |
273 | case 1: |
274 | nBadScale = QERR_QUALIFICATION_SCALE; |
275 | arRowcount[nTable].kBaseRowcount = dist_weight(NULL, "rowcounts" , nTable + nRowcountOffset + 1, 1); |
276 | break; |
277 | default: |
278 | nBadScale = QERR_BAD_SCALE; |
279 | switch (dist_member(NULL, "rowcounts" , nTable + 1, 3)) { |
280 | case 2: |
281 | arRowcount[nTable].kBaseRowcount = LinearScale(nTable + nRowcountOffset, nScale); |
282 | break; |
283 | case 1: |
284 | arRowcount[nTable].kBaseRowcount = StaticScale(nTable + nRowcountOffset, nScale); |
285 | break; |
286 | case 3: |
287 | arRowcount[nTable].kBaseRowcount = LogScale(nTable + nRowcountOffset, nScale); |
288 | break; |
289 | } /* switch(FL_SCALE_MASK) */ |
290 | break; |
291 | } /* switch(nScale) */ |
292 | |
293 | /* now adjust for the multiplier */ |
294 | nMultiplier = 1; |
295 | if (nTable < PSEUDO_TABLE_START) { |
296 | pTdef = getSimpleTdefsByNumber(nTable); |
297 | nMultiplier = (pTdef->flags & FL_TYPE_2) ? 2 : 1; |
298 | } |
299 | for (i = 1; i <= dist_member(NULL, "rowcounts" , nTable + 1, 2); i++) |
300 | nMultiplier *= 10; |
301 | arRowcount[nTable].kBaseRowcount *= nMultiplier; |
302 | |
303 | } /* for each table */ |
304 | |
305 | // if (nBadScale && !is_set("QUIET")) |
306 | // ReportErrorNoLine(nBadScale, NULL, 0); |
307 | |
308 | bScaleSet = 1; |
309 | } |
310 | |
311 | if (table == INVENTORY) |
312 | return (sc_w_inventory(nScale)); |
313 | if (table == S_INVENTORY) |
314 | return (getIDCount(ITEM) * get_rowcount(WAREHOUSE) * 6); |
315 | |
316 | return (arRowcount[table].kBaseRowcount); |
317 | } |
318 | |
319 | /* |
320 | * Routine: setUpdateDates |
321 | * Purpose: determine the dates for fact table updates |
322 | * Algorithm: |
323 | * Data Structures: |
324 | * |
325 | * Params: |
326 | * Returns: |
327 | * Called By: |
328 | * Calls: |
329 | * Assumptions: |
330 | * Side Effects: |
331 | * TODO: None |
332 | */ |
333 | void setUpdateDates(void) { |
334 | assert(0); |
335 | int nDay, nUpdate, i; |
336 | date_t dtTemp; |
337 | |
338 | nUpdate = get_int("UPDATE" ); |
339 | while (nUpdate--) { |
340 | /* pick two adjacent days in the low density zone */ |
341 | arUpdateDates[0] = getSkewedJulianDate(calendar_low, 0); |
342 | jtodt(&dtTemp, arUpdateDates[0]); |
343 | dist_weight(&nDay, "calendar" , day_number(&dtTemp) + 1, calendar_low); |
344 | if (nDay) |
345 | arUpdateDates[1] = arUpdateDates[0] + 1; |
346 | else |
347 | arUpdateDates[1] = arUpdateDates[0] - 1; |
348 | |
349 | /* |
350 | * pick the related Thursdays for inventory |
351 | * 1. shift first date to the Thursday in the current update week |
352 | * 2. move forward/back to get into correct comparability zone |
353 | * 3. set next date to next/prior Thursday based on comparability zone |
354 | */ |
355 | jtodt(&dtTemp, arUpdateDates[0] + (4 - set_dow(&dtTemp))); |
356 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_low); |
357 | arInventoryUpdateDates[0] = dtTemp.julian; |
358 | if (!nDay) { |
359 | jtodt(&dtTemp, dtTemp.julian - 7); |
360 | arInventoryUpdateDates[0] = dtTemp.julian; |
361 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_low); |
362 | if (!nDay) |
363 | arInventoryUpdateDates[0] += 14; |
364 | } |
365 | |
366 | arInventoryUpdateDates[1] = arInventoryUpdateDates[0] + 7; |
367 | jtodt(&dtTemp, arInventoryUpdateDates[1]); |
368 | dist_weight(&nDay, "calendar" , day_number(&dtTemp) + 1, calendar_low); |
369 | if (!nDay) |
370 | arInventoryUpdateDates[1] -= 14; |
371 | |
372 | /* repeat for medium calendar zone */ |
373 | arUpdateDates[2] = getSkewedJulianDate(calendar_medium, 0); |
374 | jtodt(&dtTemp, arUpdateDates[2]); |
375 | dist_weight(&nDay, "calendar" , day_number(&dtTemp) + 1, calendar_medium); |
376 | if (nDay) |
377 | arUpdateDates[3] = arUpdateDates[2] + 1; |
378 | else |
379 | arUpdateDates[3] = arUpdateDates[2] - 1; |
380 | |
381 | jtodt(&dtTemp, arUpdateDates[2] + (4 - set_dow(&dtTemp))); |
382 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_medium); |
383 | arInventoryUpdateDates[2] = dtTemp.julian; |
384 | if (!nDay) { |
385 | jtodt(&dtTemp, dtTemp.julian - 7); |
386 | arInventoryUpdateDates[2] = dtTemp.julian; |
387 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_medium); |
388 | if (!nDay) |
389 | arInventoryUpdateDates[2] += 14; |
390 | } |
391 | |
392 | arInventoryUpdateDates[3] = arInventoryUpdateDates[2] + 7; |
393 | jtodt(&dtTemp, arInventoryUpdateDates[3]); |
394 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_medium); |
395 | if (!nDay) |
396 | arInventoryUpdateDates[3] -= 14; |
397 | |
398 | /* repeat for high calendar zone */ |
399 | arUpdateDates[4] = getSkewedJulianDate(calendar_high, 0); |
400 | jtodt(&dtTemp, arUpdateDates[4]); |
401 | dist_weight(&nDay, "calendar" , day_number(&dtTemp) + 1, calendar_high); |
402 | if (nDay) |
403 | arUpdateDates[5] = arUpdateDates[4] + 1; |
404 | else |
405 | arUpdateDates[5] = arUpdateDates[4] - 1; |
406 | |
407 | jtodt(&dtTemp, arUpdateDates[4] + (4 - set_dow(&dtTemp))); |
408 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_high); |
409 | arInventoryUpdateDates[4] = dtTemp.julian; |
410 | if (!nDay) { |
411 | jtodt(&dtTemp, dtTemp.julian - 7); |
412 | arInventoryUpdateDates[4] = dtTemp.julian; |
413 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_high); |
414 | if (!nDay) |
415 | arInventoryUpdateDates[4] += 14; |
416 | } |
417 | |
418 | arInventoryUpdateDates[5] = arInventoryUpdateDates[4] + 7; |
419 | jtodt(&dtTemp, arInventoryUpdateDates[5]); |
420 | dist_weight(&nDay, "calendar" , day_number(&dtTemp), calendar_high); |
421 | if (!nDay) |
422 | arInventoryUpdateDates[5] -= 14; |
423 | } |
424 | |
425 | // /* |
426 | // * output the update dates for this update set |
427 | // */ |
428 | // openDeleteFile(1); |
429 | // for (i = 0; i < 6; i += 2) |
430 | // print_delete(&arUpdateDates[i]); |
431 | // |
432 | // /* |
433 | // * inventory uses separate dates |
434 | // */ |
435 | // openDeleteFile(2); |
436 | // for (i = 0; i < 6; i += 2) |
437 | // print_delete(&arInventoryUpdateDates[i]); |
438 | // openDeleteFile(0); |
439 | |
440 | return; |
441 | } |
442 | |
443 | /* |
444 | * Routine: |
445 | * Purpose: |
446 | * Algorithm: |
447 | * Data Structures: |
448 | * |
449 | * Params: |
450 | * Returns: |
451 | * Called By: |
452 | * Calls: |
453 | * Assumptions: |
454 | * Side Effects: |
455 | * TODO: None |
456 | */ |
457 | int getUpdateDate(int nTable, ds_key_t kRowcount) { |
458 | static int nIndex = 0, nLastTable = -1; |
459 | |
460 | if (nLastTable != nTable) { |
461 | nLastTable = nTable; |
462 | get_rowcount(nTable); |
463 | nIndex = 0; |
464 | } |
465 | |
466 | for (nIndex = 0; kRowcount > arRowcount[nTable].kDayRowcount[nIndex]; nIndex++) |
467 | if (nIndex == 5) |
468 | break; |
469 | |
470 | if (nTable == S_INVENTORY) { |
471 | return (arInventoryUpdateDates[nIndex]); |
472 | } else |
473 | return (arUpdateDates[nIndex]); |
474 | } |
475 | |
476 | /* |
477 | * Routine: getUpdateID(int nTable, ds_key_t *pDest) |
478 | * Purpose: select the primary key for an update set row |
479 | * Algorithm: |
480 | * Data Structures: |
481 | * |
482 | * Params: |
483 | * Returns: 1 if the row is new, 0 if it is reusing an existing ID |
484 | * Called By: |
485 | * Calls: |
486 | * Assumptions: |
487 | * Side Effects: |
488 | * TODO: 20040326 jms getUpdateID() this MUST be updated for 64bit -- all usages |
489 | * use casts today |
490 | * TODO: 20060102 jms this will need to be looked at for parallelism at some |
491 | * point |
492 | */ |
493 | /* |
494 | int |
495 | getUpdateID(ds_key_t *pDest, int nTable, int nColumn) |
496 | { |
497 | int bIsUpdate = 0, |
498 | nTemp; |
499 | |
500 | if (genrand_integer(NULL, DIST_UNIFORM, 0, 99, 0, nColumn) < |
501 | arRowcount[nTable].nUpdatePercentage) |
502 | { |
503 | bIsUpdate = 1; |
504 | genrand_integer(&nTemp, DIST_UNIFORM, 1, (int)getIDCount(nTable), 0, |
505 | nColumn); *pDest = (ds_key_t)nTemp; |
506 | } |
507 | else |
508 | { |
509 | *pDest = ++arRowcount[nTable].kNextInsertValue; |
510 | } |
511 | |
512 | return(bIsUpdate); |
513 | } |
514 | */ |
515 | |
516 | /* |
517 | * Routine: getSkewedJulianDate() |
518 | * Purpose: return a julian date based on the given skew and column |
519 | * Algorithm: |
520 | * Data Structures: |
521 | * |
522 | * Params: |
523 | * Returns: |
524 | * Called By: |
525 | * Calls: |
526 | * Assumptions: |
527 | * Side Effects: |
528 | * TODO: None |
529 | */ |
530 | int getSkewedJulianDate(int nWeight, int nColumn) { |
531 | int i; |
532 | date_t Date; |
533 | |
534 | pick_distribution(&i, "calendar" , 1, nWeight, nColumn); |
535 | genrand_integer(&Date.year, DIST_UNIFORM, YEAR_MINIMUM, YEAR_MAXIMUM, 0, nColumn); |
536 | dist_member(&Date.day, "calendar" , i, 3); |
537 | dist_member(&Date.month, "calendar" , i, 5); |
538 | return (dttoj(&Date)); |
539 | } |
540 | |
541 | /* |
542 | * Routine: initializeOrderUpdate() |
543 | * Purpose: skip over prior updates for the named table |
544 | * Algorithm: |
545 | * Data Structures: |
546 | * |
547 | * Params: |
548 | * Returns: |
549 | * Called By: |
550 | * Calls: |
551 | * Assumptions: |
552 | * Side Effects: |
553 | * TODO: None |
554 | */ |
555 | /* |
556 | int |
557 | initializeOrderUpdates(int nParent, int nChild, int nIDColumn, int nDateColumn, |
558 | int *pnOrderNumber) |
559 | { |
560 | int i, |
561 | nRowcount, |
562 | nRowsRemaining, |
563 | nStep = 0; |
564 | date_t Date; |
565 | |
566 | |
567 | *pnOrderNumber = 0; |
568 | |
569 | for (i=0; i < (get_int("UPDATE") - 1); i++) |
570 | { |
571 | nRowsRemaining = (int)get_rowcount(nParent); |
572 | while (nRowsRemaining > 0) |
573 | { |
574 | nStep = nStep % 3; |
575 | nStep += 1; |
576 | Date.julian = getSkewedJulianDate((nStep++ % 3) + 8, nDateColumn); |
577 | nRowcount = (int)dateScaling(getTableFromColumn(nIDColumn), |
578 | Date.julian); *pnOrderNumber += nRowcount; row_skip(nParent, nRowcount); |
579 | row_skip(nChild, LINES_PER_ORDER * nRowcount); |
580 | nRowsRemaining -= nRowcount; |
581 | } |
582 | } |
583 | |
584 | return(nStep); |
585 | } |
586 | */ |
587 | |
588 | /* |
589 | * Routine: dateScaling(int nTable, ds_key_t jDate) |
590 | * Purpose: determine the number of rows to build for a given date and fact |
591 | * table Algorithm: Data Structures: |
592 | * |
593 | * Params: |
594 | * Returns: |
595 | * Called By: |
596 | * Calls: |
597 | * Assumptions: |
598 | * Side Effects: |
599 | * TODO: None |
600 | */ |
601 | ds_key_t dateScaling(int nTable, ds_key_t jDate) { |
602 | static int bInit = 0; |
603 | static dist_t *pDist; |
604 | d_idx_t *pDistIndex; |
605 | date_t Date; |
606 | int nDateWeight = 1, nCalendarTotal, nDayWeight; |
607 | ds_key_t kRowCount = -1; |
608 | tdef *pTdef = getSimpleTdefsByNumber(nTable); |
609 | |
610 | if (!bInit) { |
611 | pDistIndex = find_dist("calendar" ); |
612 | pDist = pDistIndex->dist; |
613 | if (!pDist) |
614 | ReportError(QERR_NO_MEMORY, "dateScaling()" , 1); |
615 | bInit = 1; |
616 | } |
617 | |
618 | jtodt(&Date, (int)jDate); |
619 | |
620 | switch (nTable) { |
621 | case STORE_SALES: |
622 | case CATALOG_SALES: |
623 | case WEB_SALES: |
624 | kRowCount = get_rowcount(nTable); |
625 | nDateWeight = calendar_sales; |
626 | break; |
627 | case S_CATALOG_ORDER: |
628 | kRowCount = get_rowcount(CATALOG_SALES); |
629 | nDateWeight = calendar_sales; |
630 | break; |
631 | case S_PURCHASE: |
632 | kRowCount = get_rowcount(STORE_SALES); |
633 | nDateWeight = calendar_sales; |
634 | break; |
635 | case S_WEB_ORDER: |
636 | kRowCount = get_rowcount(WEB_SALES); |
637 | nDateWeight = calendar_sales; |
638 | break; |
639 | case S_INVENTORY: |
640 | case INVENTORY: |
641 | nDateWeight = calendar_uniform; |
642 | kRowCount = get_rowcount(WAREHOUSE) * getIDCount(ITEM); |
643 | break; |
644 | default: |
645 | ReportErrorNoLine(QERR_TABLE_NOP, pTdef->name, 1); |
646 | break; |
647 | } |
648 | |
649 | if (nTable != INVENTORY) /* inventory rowcount is uniform thorughout the year */ |
650 | { |
651 | if (is_leap(Date.year)) |
652 | nDateWeight += 1; |
653 | |
654 | nCalendarTotal = dist_max(pDist, nDateWeight); |
655 | nCalendarTotal *= 5; /* assumes date range is 5 years */ |
656 | |
657 | dist_weight(&nDayWeight, "calendar" , day_number(&Date), nDateWeight); |
658 | kRowCount *= nDayWeight; |
659 | kRowCount += nCalendarTotal / 2; |
660 | kRowCount /= nCalendarTotal; |
661 | } |
662 | |
663 | return (kRowCount); |
664 | } |
665 | |
666 | /* |
667 | * Routine: getUpdateBase(int nTable) |
668 | * Purpose: return the offset to the first order in this update set for a given |
669 | * table Algorithm: Data Structures: |
670 | * |
671 | * Params: |
672 | * Returns: |
673 | * Called By: |
674 | * Calls: |
675 | * Assumptions: |
676 | * Side Effects: |
677 | * TODO: None |
678 | */ |
679 | ds_key_t getUpdateBase(int nTable) { |
680 | return (arRowcount[nTable - S_BRAND].kNextInsertValue); |
681 | } |
682 | |
683 | /* |
684 | * Routine: |
685 | * Purpose: |
686 | * Algorithm: |
687 | * Data Structures: |
688 | * |
689 | * Params: |
690 | * Returns: |
691 | * Called By: |
692 | * Calls: |
693 | * Assumptions: |
694 | * Side Effects: |
695 | * TODO: None |
696 | */ |
697 | void setUpdateScaling(int nTable) { |
698 | tdef *pTdef; |
699 | int i, nBaseTable; |
700 | ds_key_t kNewRowcount = 0; |
701 | |
702 | pTdef = getSimpleTdefsByNumber(nTable); |
703 | if (!(pTdef->flags & FL_SOURCE_DDL) || !(pTdef->flags & FL_DATE_BASED) || (pTdef->flags & FL_NOP)) |
704 | return; |
705 | |
706 | switch (nTable) { |
707 | case S_PURCHASE: |
708 | nBaseTable = STORE_SALES; |
709 | break; |
710 | case S_CATALOG_ORDER: |
711 | nBaseTable = CATALOG_SALES; |
712 | break; |
713 | case S_WEB_ORDER: |
714 | nBaseTable = WEB_SALES; |
715 | break; |
716 | case S_INVENTORY: |
717 | nBaseTable = INVENTORY; |
718 | break; |
719 | default: |
720 | fprintf(stderr, "ERROR: Invalid table in setUpdateScaling\n" ); |
721 | exit(1); |
722 | break; |
723 | } |
724 | |
725 | arRowcount[nTable].kNextInsertValue = arRowcount[nTable].kBaseRowcount; |
726 | |
727 | for (i = 0; i < 6; i++) { |
728 | kNewRowcount += dateScaling(nBaseTable, arUpdateDates[i]); |
729 | arRowcount[nTable].kDayRowcount[i] = kNewRowcount; |
730 | } |
731 | |
732 | arRowcount[nTable].kBaseRowcount = kNewRowcount; |
733 | arRowcount[nTable].kNextInsertValue += kNewRowcount * (get_int("update" ) - 1); |
734 | |
735 | return; |
736 | } |
737 | |