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 |
12 | long name_bits[MAX_COLOR / BITS_PER_LONG]; |
13 | extern seed_t Seed[]; |
14 | void fakeVStr(int nAvg, long nSeed, DSS_HUGE nCount); |
15 | void NthElement(DSS_HUGE N, DSS_HUGE *StartSeed); |
16 | |
17 | void 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 | |
37 | static DSS_HUGE Multiplier = 16807; /* or whatever nonstandard */ |
38 | static 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 */ |
57 | void 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 */ |
81 | void 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 | |
97 | long 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 | |
110 | long 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 | |
133 | long 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 | |
151 | long 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 | |
165 | long 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 | |
177 | long 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 | |