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