1 /*
2 Copyright (C) 2003-2006 MySQL AB, 2008, 2010 Sun Microsystems, Inc.
3 All rights reserved. Use is subject to license terms.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation. The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License, version 2.0, for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 /***************************************************************
27 * I N C L U D E D F I L E S *
28 ***************************************************************/
29
30 #include <ndb_global.h>
31
32 #include <NdbOut.hpp>
33
34 #include <random.h>
35
36 /***************************************************************
37 * L O C A L C O N S T A N T S *
38 ***************************************************************/
39
40 /***************************************************************
41 * L O C A L D A T A S T R U C T U R E S *
42 ***************************************************************/
43
44 typedef struct {
45 unsigned short int x[3]; /* Current state. */
46 unsigned short int a[3]; /* Factor in congruential formula. */
47 unsigned short int c; /* Additive const. in congruential formula. */
48 int init; /* Flag for initializing. */
49 }DRand48Data;
50
51 /***************************************************************
52 * L O C A L F U N C T I O N S *
53 ***************************************************************/
54
55 static void shuffleSequence(RandomSequence *seq);
56
57 /***************************************************************
58 * L O C A L D A T A *
59 ***************************************************************/
60
61 static DRand48Data dRand48Data;
62
63 /***************************************************************
64 * P U B L I C D A T A *
65 ***************************************************************/
66
67
68 /***************************************************************
69 ****************************************************************
70 * L O C A L F U N C T I O N S C O D E S E C T I O N *
71 ****************************************************************
72 ***************************************************************/
73
localRandom48Init(long int seedval,DRand48Data * buffer)74 static void localRandom48Init(long int seedval, DRand48Data *buffer)
75 {
76 /* The standards say we only have 32 bits. */
77 if (sizeof (long int) > 4)
78 seedval &= 0xffffffffl;
79
80 #if USHRT_MAX == 0xffffU
81 buffer->x[2] = (unsigned short)(seedval >> 16);
82 buffer->x[1] = (unsigned short)(seedval & 0xffffl);
83 buffer->x[0] = 0x330e;
84
85 buffer->a[2] = 0x5;
86 buffer->a[1] = 0xdeec;
87 buffer->a[0] = 0xe66d;
88 #else
89 buffer->x[2] = seedval;
90 buffer->x[1] = 0x330e0000UL;
91 buffer->x[0] = 0;
92
93 buffer->a[2] = 0x5deecUL;
94 buffer->a[1] = 0xe66d0000UL;
95 buffer->a[0] = 0;
96 #endif
97
98 buffer->c = 0xb;
99 buffer->init = 1;
100 }
101
localRandom48(DRand48Data * buffer,long int * result)102 static void localRandom48(DRand48Data *buffer, long int *result)
103 {
104 Uint64 X;
105 Uint64 a;
106 Uint64 loc_result;
107
108 /*--------------------------------------*/
109 /* Initialize buffer, if not yet done. */
110 /*--------------------------------------*/
111 if (!buffer->init) {
112 #if (USHRT_MAX == 0xffffU)
113 buffer->a[2] = 0x5;
114 buffer->a[1] = 0xdeec;
115 buffer->a[0] = 0xe66d;
116 #else
117 buffer->a[2] = 0x5deecUL;
118 buffer->a[1] = 0xe66d0000UL;
119 buffer->a[0] = 0;
120 #endif
121 buffer->c = 0xb;
122 buffer->init = 1;
123 }
124
125 /* Do the real work. We choose a data type which contains at least
126 48 bits. Because we compute the modulus it does not care how
127 many bits really are computed. */
128
129 if (sizeof (unsigned short int) == 2) {
130 X = (Uint64)buffer->x[2] << 32 |
131 (Uint64)buffer->x[1] << 16 |
132 buffer->x[0];
133 a = ((Uint64)buffer->a[2] << 32 |
134 (Uint64)buffer->a[1] << 16 |
135 buffer->a[0]);
136
137 loc_result = X * a + buffer->c;
138
139 buffer->x[0] = (unsigned short)(loc_result & 0xffff);
140 buffer->x[1] = (unsigned short)((loc_result >> 16) & 0xffff);
141 buffer->x[2] = (unsigned short)((loc_result >> 32) & 0xffff);
142 }
143 else {
144 X = (Uint64)buffer->x[2] << 16 |
145 (Uint64)buffer->x[1] >> 16;
146 a = (Uint64)buffer->a[2] << 16 |
147 (Uint64)buffer->a[1] >> 16;
148
149 loc_result = X * a + buffer->c;
150
151 buffer->x[0] = (unsigned short)(loc_result >> 16 & 0xffffffffl);
152 buffer->x[1] = (unsigned short)(loc_result << 16 & 0xffff0000l);
153 }
154
155 /*--------------------*/
156 /* Store the result. */
157 /*--------------------*/
158 if (sizeof (unsigned short int) == 2)
159 *result = buffer->x[2] << 15 | buffer->x[1] >> 1;
160 else
161 *result = buffer->x[2] >> 1;
162 }
163
shuffleSequence(RandomSequence * seq)164 static void shuffleSequence(RandomSequence *seq)
165 {
166 unsigned int i;
167 unsigned int j;
168 unsigned int tmp;
169
170 if( !seq ) return;
171
172 for(i = 0; i < seq->length; i++ ) {
173 j = myRandom48(seq->length);
174 if( i != j ) {
175 tmp = seq->values[i];
176 seq->values[i] = seq->values[j];
177 seq->values[j] = tmp;
178 }
179 }
180 }
181
182
183 /***************************************************************
184 ****************************************************************
185 * P U B L I C F U N C T I O N S C O D E S E C T I O N *
186 ****************************************************************
187 ***************************************************************/
188
189
getTps(unsigned int count,double timeValue)190 double getTps(unsigned int count, double timeValue)
191 {
192 double f;
193
194 if( timeValue != 0.0 )
195 f = count / timeValue;
196 else
197 f = 0.0;
198
199 return(f);
200 }
201
202 /*----------------------------*/
203 /* Random Sequences Functions */
204 /*----------------------------*/
initSequence(RandomSequence * seq,SequenceValues * inputValues)205 int initSequence(RandomSequence *seq, SequenceValues *inputValues)
206 {
207 unsigned int i;
208 unsigned int j;
209 unsigned int totalLength;
210 unsigned int idx;
211
212 if( !seq || !inputValues ) return(-1);
213
214 /*------------------------------------*/
215 /* Find the total length of the array */
216 /*------------------------------------*/
217 totalLength = 0;
218
219 for(i = 0; inputValues[i].length != 0; i++)
220 totalLength += inputValues[i].length;
221
222 if( totalLength == 0 ) return(-1);
223
224 seq->length = totalLength;
225 seq->values = calloc(totalLength, sizeof(unsigned int));
226
227 if( seq->values == 0 ) return(-1);
228
229 /*----------------------*/
230 /* set the array values */
231 /*----------------------*/
232 idx = 0;
233
234 for(i = 0; inputValues[i].length != 0; i++) {
235 for(j = 0; j < inputValues[i].length; j++ ) {
236 seq->values[idx] = inputValues[i].value;
237 idx++;
238 }
239 }
240
241 shuffleSequence(seq);
242
243 seq->currentIndex = 0;
244
245 return(0);
246 }
247
getNextRandom(RandomSequence * seq)248 unsigned int getNextRandom(RandomSequence *seq)
249 {
250 unsigned int nextValue;
251
252 nextValue = seq->values[seq->currentIndex];
253
254 seq->currentIndex++;
255
256 if(seq->currentIndex == seq->length){
257 seq->currentIndex = 0;
258 shuffleSequence(seq);
259 }
260
261 return nextValue;
262 }
263
printSequence(RandomSequence * seq,unsigned int numPerRow)264 void printSequence(RandomSequence *seq, unsigned int numPerRow)
265 {
266 unsigned int i;
267
268 if( !seq ) return;
269
270 for(i = 0; i<seq->length; i++) {
271 ndbout_c("%d ", seq->values[i]);
272
273 if((i+1) % numPerRow == 0)
274 ndbout_c("%s", "");
275 }
276
277 if(i % numPerRow != 0)
278 ndbout_c("%s", "");
279 }
280
myRandom48Init(long int seedval)281 void myRandom48Init(long int seedval)
282 {
283 localRandom48Init(seedval, &dRand48Data);
284 }
285
myRandom48(unsigned int maxValue)286 long int myRandom48(unsigned int maxValue)
287 {
288 long int result;
289
290 localRandom48(&dRand48Data, &result);
291
292 return(result % maxValue);
293 }
294