random.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /***************************************************************
  14. * I N C L U D E D   F I L E S                                  *
  15. ***************************************************************/
  16. #include <ndb_global.h>
  17. #include <NdbOut.hpp>
  18. #include <random.h>
  19. /***************************************************************
  20. * L O C A L   C O N S T A N T S                                *
  21. ***************************************************************/
  22. /***************************************************************
  23. * L O C A L   D A T A   S T R U C T U R E S                    *
  24. ***************************************************************/
  25. typedef struct {
  26.     unsigned short int x[3]; /* Current state.  */
  27.     unsigned short int a[3]; /* Factor in congruential formula.  */
  28.     unsigned short int c; /* Additive const. in congruential formula.  */
  29.     int init; /* Flag for initializing.  */
  30. }DRand48Data;
  31. /***************************************************************
  32. * L O C A L   F U N C T I O N S                                *
  33. ***************************************************************/
  34. static void shuffleSequence(RandomSequence *seq);
  35. /***************************************************************
  36. * L O C A L   D A T A                                          *
  37. ***************************************************************/
  38. static DRand48Data dRand48Data;
  39. /***************************************************************
  40. * P U B L I C   D A T A                                        *
  41. ***************************************************************/
  42. /***************************************************************
  43. ****************************************************************
  44. * 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      *
  45. ****************************************************************
  46. ***************************************************************/
  47. static void localRandom48Init(long int seedval, DRand48Data *buffer)
  48. {
  49.    /* The standards say we only have 32 bits.  */
  50.    if (sizeof (long int) > 4)
  51.       seedval &= 0xffffffffl;
  52. #if USHRT_MAX == 0xffffU
  53.   buffer->x[2] = seedval >> 16;
  54.   buffer->x[1] = seedval & 0xffffl;
  55.   buffer->x[0] = 0x330e;
  56.   buffer->a[2] = 0x5;
  57.   buffer->a[1] = 0xdeec;
  58.   buffer->a[0] = 0xe66d;
  59. #else
  60.   buffer->x[2] = seedval;
  61.   buffer->x[1] = 0x330e0000UL;
  62.   buffer->x[0] = 0;
  63.   buffer->a[2] = 0x5deecUL;
  64.   buffer->a[1] = 0xe66d0000UL;
  65.   buffer->a[0] = 0;
  66. #endif
  67.   buffer->c    = 0xb;
  68.   buffer->init = 1;
  69. }
  70. static void localRandom48(DRand48Data *buffer, long int *result)
  71. {
  72.    Uint64 X;
  73.    Uint64 a;
  74.    Uint64 loc_result;
  75.    /*--------------------------------------*/
  76.    /* Initialize buffer, if not yet done.  */
  77.    /*--------------------------------------*/
  78.    if (!buffer->init) {
  79. #if (USHRT_MAX == 0xffffU)
  80.       buffer->a[2] = 0x5;
  81.       buffer->a[1] = 0xdeec;
  82.       buffer->a[0] = 0xe66d;
  83. #else
  84.       buffer->a[2] = 0x5deecUL;
  85.       buffer->a[1] = 0xe66d0000UL;
  86.       buffer->a[0] = 0;
  87. #endif
  88.       buffer->c    = 0xb;
  89.       buffer->init = 1;
  90.    }
  91.    /* Do the real work.  We choose a data type which contains at least
  92.       48 bits.  Because we compute the modulus it does not care how
  93.       many bits really are computed.  */
  94.    if (sizeof (unsigned short int) == 2) {
  95.       X = (Uint64)buffer->x[2] << 32 | 
  96.           (Uint64)buffer->x[1] << 16 | 
  97.            buffer->x[0];
  98.       a = ((Uint64)buffer->a[2] << 32 |
  99.            (Uint64)buffer->a[1] << 16 |
  100.     buffer->a[0]);
  101.       loc_result = X * a + buffer->c;
  102.       buffer->x[0] = loc_result & 0xffff;
  103.       buffer->x[1] = (loc_result >> 16) & 0xffff;
  104.       buffer->x[2] = (loc_result >> 32) & 0xffff;
  105.    }
  106.    else {
  107.       X = (Uint64)buffer->x[2] << 16 | 
  108.            buffer->x[1] >> 16;
  109.       a = (Uint64)buffer->a[2] << 16 |
  110.            buffer->a[1] >> 16;
  111.       loc_result = X * a + buffer->c;
  112.       buffer->x[0] = loc_result >> 16 & 0xffffffffl;
  113.       buffer->x[1] = loc_result << 16 & 0xffff0000l;
  114.    }
  115.    /*--------------------*/
  116.    /* Store the result.  */
  117.    /*--------------------*/
  118.    if (sizeof (unsigned short int) == 2)
  119.       *result = buffer->x[2] << 15 | buffer->x[1] >> 1;
  120.    else
  121.       *result = buffer->x[2] >> 1;
  122. }
  123. static void shuffleSequence(RandomSequence *seq)
  124. {
  125.    unsigned int i;
  126.    unsigned int j;
  127.    unsigned int tmp;
  128.    if( !seq ) return;
  129.    for(i = 0; i < seq->length; i++ ) {
  130.       j = myRandom48(seq->length);
  131.       if( i != j ) {
  132.          tmp = seq->values[i];
  133.          seq->values[i] = seq->values[j];
  134.          seq->values[j] = tmp;
  135.       }
  136.    }
  137. }
  138. /***************************************************************
  139. ****************************************************************
  140. * 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    *
  141. ****************************************************************
  142. ***************************************************************/
  143. double getTps(unsigned int count, double timeValue)
  144. {
  145.    double f;
  146.    if( timeValue != 0.0 )
  147.       f = count / timeValue;
  148.    else
  149.       f = 0.0;
  150.    return(f);
  151. }
  152. /*----------------------------*/
  153. /* Random Sequences Functions */
  154. /*----------------------------*/
  155. int initSequence(RandomSequence *seq, SequenceValues *inputValues)
  156. {
  157.    unsigned int i;
  158.    unsigned int j;
  159.    unsigned int totalLength;
  160.    unsigned int index;
  161.    if( !seq || !inputValues ) return(-1);
  162.    /*------------------------------------*/
  163.    /* Find the total length of the array */
  164.    /*------------------------------------*/
  165.    totalLength = 0;
  166.    for(i = 0; inputValues[i].length != 0; i++)
  167.       totalLength += inputValues[i].length;
  168.    if( totalLength == 0 ) return(-1);
  169.    seq->length = totalLength;
  170.    seq->values = calloc(totalLength, sizeof(unsigned int));
  171.    if( seq->values == 0 ) return(-1);
  172.    /*----------------------*/
  173.    /* set the array values */
  174.    /*----------------------*/
  175.    index = 0;
  176.    for(i = 0; inputValues[i].length != 0; i++) {
  177.       for(j = 0; j < inputValues[i].length; j++ ) {
  178.          seq->values[index] = inputValues[i].value;
  179.          index++;
  180.       }
  181.    }
  182.    shuffleSequence(seq);
  183.    seq->currentIndex = 0;
  184.    return(0);
  185. }
  186. unsigned int getNextRandom(RandomSequence *seq)
  187. {
  188.   unsigned int nextValue;
  189.   
  190.   nextValue = seq->values[seq->currentIndex];
  191.   seq->currentIndex++;
  192.   if(seq->currentIndex == seq->length){
  193.     seq->currentIndex = 0;
  194.     shuffleSequence(seq);
  195.   }
  196.   return nextValue;
  197. }
  198. void printSequence(RandomSequence *seq, unsigned int numPerRow)
  199. {
  200.    unsigned int i;
  201.    if( !seq ) return;
  202.    for(i = 0; i<seq->length; i++) {
  203.       ndbout_c("%d ", seq->values[i]);
  204.       if((i+1) % numPerRow == 0)
  205.          ndbout_c("");
  206.    }
  207.    if(i % numPerRow != 0)
  208.       ndbout_c("");
  209. }
  210. void myRandom48Init(long int seedval)
  211. {
  212.    localRandom48Init(seedval, &dRand48Data);
  213. }
  214. long int myRandom48(unsigned int maxValue)
  215. {
  216.    long int result;
  217.    localRandom48(&dRand48Data, &result);
  218.    return(result % maxValue);
  219. }