summaryrefslogtreecommitdiff
path: root/storage/ndb/src/common/util/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/common/util/random.c')
-rw-r--r--storage/ndb/src/common/util/random.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/storage/ndb/src/common/util/random.c b/storage/ndb/src/common/util/random.c
new file mode 100644
index 00000000000..21235763793
--- /dev/null
+++ b/storage/ndb/src/common/util/random.c
@@ -0,0 +1,284 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/***************************************************************
+* I N C L U D E D F I L E S *
+***************************************************************/
+
+#include <ndb_global.h>
+
+#include <NdbOut.hpp>
+
+#include <random.h>
+
+/***************************************************************
+* L O C A L C O N S T A N T S *
+***************************************************************/
+
+/***************************************************************
+* L O C A L D A T A S T R U C T U R E S *
+***************************************************************/
+
+typedef struct {
+ unsigned short int x[3]; /* Current state. */
+ unsigned short int a[3]; /* Factor in congruential formula. */
+ unsigned short int c; /* Additive const. in congruential formula. */
+ int init; /* Flag for initializing. */
+}DRand48Data;
+
+/***************************************************************
+* L O C A L F U N C T I O N S *
+***************************************************************/
+
+static void shuffleSequence(RandomSequence *seq);
+
+/***************************************************************
+* L O C A L D A T A *
+***************************************************************/
+
+static DRand48Data dRand48Data;
+
+/***************************************************************
+* P U B L I C D A T A *
+***************************************************************/
+
+
+/***************************************************************
+****************************************************************
+* 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 *
+****************************************************************
+***************************************************************/
+
+static void localRandom48Init(long int seedval, DRand48Data *buffer)
+{
+ /* The standards say we only have 32 bits. */
+ if (sizeof (long int) > 4)
+ seedval &= 0xffffffffl;
+
+#if USHRT_MAX == 0xffffU
+ buffer->x[2] = seedval >> 16;
+ buffer->x[1] = seedval & 0xffffl;
+ buffer->x[0] = 0x330e;
+
+ buffer->a[2] = 0x5;
+ buffer->a[1] = 0xdeec;
+ buffer->a[0] = 0xe66d;
+#else
+ buffer->x[2] = seedval;
+ buffer->x[1] = 0x330e0000UL;
+ buffer->x[0] = 0;
+
+ buffer->a[2] = 0x5deecUL;
+ buffer->a[1] = 0xe66d0000UL;
+ buffer->a[0] = 0;
+#endif
+
+ buffer->c = 0xb;
+ buffer->init = 1;
+}
+
+static void localRandom48(DRand48Data *buffer, long int *result)
+{
+ Uint64 X;
+ Uint64 a;
+ Uint64 loc_result;
+
+ /*--------------------------------------*/
+ /* Initialize buffer, if not yet done. */
+ /*--------------------------------------*/
+ if (!buffer->init) {
+#if (USHRT_MAX == 0xffffU)
+ buffer->a[2] = 0x5;
+ buffer->a[1] = 0xdeec;
+ buffer->a[0] = 0xe66d;
+#else
+ buffer->a[2] = 0x5deecUL;
+ buffer->a[1] = 0xe66d0000UL;
+ buffer->a[0] = 0;
+#endif
+ buffer->c = 0xb;
+ buffer->init = 1;
+ }
+
+ /* Do the real work. We choose a data type which contains at least
+ 48 bits. Because we compute the modulus it does not care how
+ many bits really are computed. */
+
+ if (sizeof (unsigned short int) == 2) {
+ X = (Uint64)buffer->x[2] << 32 |
+ (Uint64)buffer->x[1] << 16 |
+ buffer->x[0];
+ a = ((Uint64)buffer->a[2] << 32 |
+ (Uint64)buffer->a[1] << 16 |
+ buffer->a[0]);
+
+ loc_result = X * a + buffer->c;
+
+ buffer->x[0] = loc_result & 0xffff;
+ buffer->x[1] = (loc_result >> 16) & 0xffff;
+ buffer->x[2] = (loc_result >> 32) & 0xffff;
+ }
+ else {
+ X = (Uint64)buffer->x[2] << 16 |
+ buffer->x[1] >> 16;
+ a = (Uint64)buffer->a[2] << 16 |
+ buffer->a[1] >> 16;
+
+ loc_result = X * a + buffer->c;
+
+ buffer->x[0] = loc_result >> 16 & 0xffffffffl;
+ buffer->x[1] = loc_result << 16 & 0xffff0000l;
+ }
+
+ /*--------------------*/
+ /* Store the result. */
+ /*--------------------*/
+ if (sizeof (unsigned short int) == 2)
+ *result = buffer->x[2] << 15 | buffer->x[1] >> 1;
+ else
+ *result = buffer->x[2] >> 1;
+}
+
+static void shuffleSequence(RandomSequence *seq)
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int tmp;
+
+ if( !seq ) return;
+
+ for(i = 0; i < seq->length; i++ ) {
+ j = myRandom48(seq->length);
+ if( i != j ) {
+ tmp = seq->values[i];
+ seq->values[i] = seq->values[j];
+ seq->values[j] = tmp;
+ }
+ }
+}
+
+
+/***************************************************************
+****************************************************************
+* 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 *
+****************************************************************
+***************************************************************/
+
+
+double getTps(unsigned int count, double timeValue)
+{
+ double f;
+
+ if( timeValue != 0.0 )
+ f = count / timeValue;
+ else
+ f = 0.0;
+
+ return(f);
+}
+
+/*----------------------------*/
+/* Random Sequences Functions */
+/*----------------------------*/
+int initSequence(RandomSequence *seq, SequenceValues *inputValues)
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int totalLength;
+ unsigned int index;
+
+ if( !seq || !inputValues ) return(-1);
+
+ /*------------------------------------*/
+ /* Find the total length of the array */
+ /*------------------------------------*/
+ totalLength = 0;
+
+ for(i = 0; inputValues[i].length != 0; i++)
+ totalLength += inputValues[i].length;
+
+ if( totalLength == 0 ) return(-1);
+
+ seq->length = totalLength;
+ seq->values = calloc(totalLength, sizeof(unsigned int));
+
+ if( seq->values == 0 ) return(-1);
+
+ /*----------------------*/
+ /* set the array values */
+ /*----------------------*/
+ index = 0;
+
+ for(i = 0; inputValues[i].length != 0; i++) {
+ for(j = 0; j < inputValues[i].length; j++ ) {
+ seq->values[index] = inputValues[i].value;
+ index++;
+ }
+ }
+
+ shuffleSequence(seq);
+
+ seq->currentIndex = 0;
+
+ return(0);
+}
+
+unsigned int getNextRandom(RandomSequence *seq)
+{
+ unsigned int nextValue;
+
+ nextValue = seq->values[seq->currentIndex];
+
+ seq->currentIndex++;
+
+ if(seq->currentIndex == seq->length){
+ seq->currentIndex = 0;
+ shuffleSequence(seq);
+ }
+
+ return nextValue;
+}
+
+void printSequence(RandomSequence *seq, unsigned int numPerRow)
+{
+ unsigned int i;
+
+ if( !seq ) return;
+
+ for(i = 0; i<seq->length; i++) {
+ ndbout_c("%d ", seq->values[i]);
+
+ if((i+1) % numPerRow == 0)
+ ndbout_c("");
+ }
+
+ if(i % numPerRow != 0)
+ ndbout_c("");
+}
+
+void myRandom48Init(long int seedval)
+{
+ localRandom48Init(seedval, &dRand48Data);
+}
+
+long int myRandom48(unsigned int maxValue)
+{
+ long int result;
+
+ localRandom48(&dRand48Data, &result);
+
+ return(result % maxValue);
+}