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