1#include "dss.h"
2#include "rng64.h"
3
4#include <stdio.h>
5#include <stdlib.h>
6
7/* _tal long RandSeed = "Random^SeedFromTimestamp" (void); */
8
9#define ADVANCE_STREAM(stream_id, num_calls) advanceStream(stream_id, num_calls, 0)
10#define ADVANCE_STREAM64(stream_id, num_calls) advanceStream(stream_id, num_calls, 1)
11#define MAX_COLOR 92
12long name_bits[MAX_COLOR / BITS_PER_LONG];
13extern seed_t Seed[];
14void fakeVStr(int nAvg, long nSeed, DSS_HUGE nCount);
15void NthElement(DSS_HUGE N, DSS_HUGE *StartSeed);
16
17void advanceStream(int nStream, DSS_HUGE nCalls, int bUse64Bit) {
18 if (bUse64Bit)
19 Seed[nStream].value = AdvanceRand64(Seed[nStream].value, nCalls);
20 else
21 NthElement(nCalls, &Seed[nStream].value);
22
23#ifdef RNG_TEST
24 Seed[nStream].nCalls += nCalls;
25#endif
26
27 return;
28}
29
30/* WARNING! This routine assumes the existence of 64-bit */
31/* integers. The notation used here- "HUGE" is *not* ANSI standard. */
32/* Hopefully, you have this extension as well. If not, use whatever */
33/* nonstandard trick you need to in order to get 64 bit integers. */
34/* The book says that this will work if MAXINT for the type you choose */
35/* is at least 2**46 - 1, so 64 bits is more than you *really* need */
36
37static DSS_HUGE Multiplier = 16807; /* or whatever nonstandard */
38static DSS_HUGE Modulus = 2147483647; /* trick you use to get 64 bit int */
39
40/* Advances value of Seed after N applications of the random number generator
41 with multiplier Mult and given Modulus.
42 NthElement(Seed[],count);
43
44 Theory: We are using a generator of the form
45 X_n = [Mult * X_(n-1)] mod Modulus. It turns out that
46 X_n = [(Mult ** n) X_0] mod Modulus.
47 This can be computed using a divide-and-conquer technique, see
48 the code below.
49
50 In words, this means that if you want the value of the Seed after n
51 applications of the generator, you multiply the initial value of the
52 Seed by the "super multiplier" which is the basic multiplier raised
53 to the nth power, and then take mod Modulus.
54*/
55
56/* Nth Element of sequence starting with StartSeed */
57void NthElement(DSS_HUGE N, DSS_HUGE *StartSeed) {
58 DSS_HUGE Z;
59 DSS_HUGE Mult;
60 static int ln = -1;
61 int i;
62
63 if ((verbose > 0) && ++ln % 1000 == 0) {
64 i = ln % LN_CNT;
65 fprintf(stderr, "%c\b", lnoise[i]);
66 }
67 Mult = Multiplier;
68 Z = (DSS_HUGE)*StartSeed;
69 while (N > 0) {
70 if (N % 2 != 0) /* testing for oddness, this seems portable */
71 Z = (Mult * Z) % Modulus;
72 N = N / 2; /* integer division, truncates */
73 Mult = (Mult * Mult) % Modulus;
74 }
75 *StartSeed = Z;
76
77 return;
78}
79
80/* updates Seed[column] using the a_rnd algorithm */
81void fake_a_rnd(int min, int max, int column) {
82 DSS_HUGE len;
83 DSS_HUGE itcount;
84
85 RANDOM(len, min, max, column);
86 if (len % 5L == 0)
87 itcount = len / 5;
88 else
89 itcount = len / 5 + 1L;
90 NthElement(itcount, &Seed[column].usage);
91#ifdef RNG_TEST
92 Seed[column].nCalls += itcount;
93#endif
94 return;
95}
96
97long sd_part(int child, DSS_HUGE skip_count) {
98 (void)child;
99 int i;
100
101 for (i = P_MFG_SD; i <= P_CNTR_SD; i++)
102 ADVANCE_STREAM(i, skip_count);
103
104 ADVANCE_STREAM(P_CMNT_SD, skip_count * 2);
105 ADVANCE_STREAM(P_NAME_SD, skip_count * 92);
106
107 return (0L);
108}
109
110long sd_line(int child, DSS_HUGE skip_count) {
111 int i, j;
112
113 for (j = 0; j < O_LCNT_MAX; j++) {
114 for (i = L_QTY_SD; i <= L_RFLG_SD; i++)
115 /*
116 if (scale >= 30000 && i == L_PKEY_SD)
117 ADVANCE_STREAM64(i, skip_count);
118 else
119 */
120 ADVANCE_STREAM(i, skip_count);
121 ADVANCE_STREAM(L_CMNT_SD, skip_count * 2);
122 }
123
124 /* need to special case this as the link between master and detail */
125 if (child == 1) {
126 ADVANCE_STREAM(O_ODATE_SD, skip_count);
127 ADVANCE_STREAM(O_LCNT_SD, skip_count);
128 }
129
130 return (0L);
131}
132
133long sd_order(int child, DSS_HUGE skip_count) {
134 (void)child;
135 ADVANCE_STREAM(O_LCNT_SD, skip_count);
136 /*
137 if (scale >= 30000)
138 ADVANCE_STREAM64(O_CKEY_SD, skip_count);
139 else
140 */
141 ADVANCE_STREAM(O_CKEY_SD, skip_count);
142 ADVANCE_STREAM(O_CMNT_SD, skip_count * 2);
143 ADVANCE_STREAM(O_SUPP_SD, skip_count);
144 ADVANCE_STREAM(O_CLRK_SD, skip_count);
145 ADVANCE_STREAM(O_PRIO_SD, skip_count);
146 ADVANCE_STREAM(O_ODATE_SD, skip_count);
147
148 return (0L);
149}
150
151long sd_psupp(int child, DSS_HUGE skip_count) {
152 (void)child;
153
154 int j;
155
156 for (j = 0; j < SUPP_PER_PART; j++) {
157 ADVANCE_STREAM(PS_QTY_SD, skip_count);
158 ADVANCE_STREAM(PS_SCST_SD, skip_count);
159 ADVANCE_STREAM(PS_CMNT_SD, skip_count * 2);
160 }
161
162 return (0L);
163}
164
165long sd_cust(int child, DSS_HUGE skip_count) {
166 (void)child;
167
168 ADVANCE_STREAM(C_ADDR_SD, skip_count * 9);
169 ADVANCE_STREAM(C_CMNT_SD, skip_count * 2);
170 ADVANCE_STREAM(C_NTRG_SD, skip_count);
171 ADVANCE_STREAM(C_PHNE_SD, 3L * skip_count);
172 ADVANCE_STREAM(C_ABAL_SD, skip_count);
173 ADVANCE_STREAM(C_MSEG_SD, skip_count);
174 return (0L);
175}
176
177long sd_supp(int child, DSS_HUGE skip_count) {
178 (void)child;
179
180 ADVANCE_STREAM(S_NTRG_SD, skip_count);
181 ADVANCE_STREAM(S_PHNE_SD, 3L * skip_count);
182 ADVANCE_STREAM(S_ABAL_SD, skip_count);
183 ADVANCE_STREAM(S_ADDR_SD, skip_count * 9);
184 ADVANCE_STREAM(S_CMNT_SD, skip_count * 2);
185 ADVANCE_STREAM(BBB_CMNT_SD, skip_count);
186 ADVANCE_STREAM(BBB_JNK_SD, skip_count);
187 ADVANCE_STREAM(BBB_OFFSET_SD, skip_count);
188 ADVANCE_STREAM(BBB_TYPE_SD, skip_count); /* avoid one trudge */
189
190 return (0L);
191}
192