ut0rnd.cc 2.35 KB
Newer Older
Vadim Tkachenko's avatar
Vadim Tkachenko committed
1 2
/*****************************************************************************

3
Copyright (c) 1994, 2009, Oracle and/or its affiliates. All Rights Reserved.
Vadim Tkachenko's avatar
Vadim Tkachenko committed
4 5 6 7 8 9 10 11 12 13

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; version 2 of the License.

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
14 15
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
Vadim Tkachenko's avatar
Vadim Tkachenko committed
16 17 18

*****************************************************************************/

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
19
/***************************************************************//**
20
@file ut/ut0rnd.cc
21 22 23 24 25 26 27 28 29 30 31
Random numbers and hashing

Created 5/11/1994 Heikki Tuuri
********************************************************************/

#include "ut0rnd.h"

#ifdef UNIV_NONINL
#include "ut0rnd.ic"
#endif

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
32 33
/** These random numbers are used in ut_find_prime */
/*@{*/
34 35 36
#define	UT_RANDOM_1	1.0412321
#define	UT_RANDOM_2	1.1131347
#define UT_RANDOM_3	1.0132677
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
37
/*@}*/
38

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
39
/** Seed value of ut_rnd_gen_ulint(). */
40 41
UNIV_INTERN ulint	ut_rnd_ulint_counter = 65654363;

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
42
/***********************************************************//**
43
Looks for a prime number slightly greater than the given argument.
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
44 45
The prime is chosen so that it is not near any power of 2.
@return	prime */
46 47 48 49
UNIV_INTERN
ulint
ut_find_prime(
/*==========*/
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
50
	ulint	n)	/*!< in: positive number > 100 */
51 52 53 54 55 56 57 58 59 60 61
{
	ulint	pow2;
	ulint	i;

	n += 100;

	pow2 = 1;
	while (pow2 * 2 < n) {
		pow2 = 2 * pow2;
	}

62 63
	if ((double) n < 1.05 * (double) pow2) {
		n = (ulint) ((double) n * UT_RANDOM_1);
64 65 66 67
	}

	pow2 = 2 * pow2;

68 69
	if ((double) n > 0.95 * (double) pow2) {
		n = (ulint) ((double) n * UT_RANDOM_2);
70 71 72 73 74 75 76 77 78 79
	}

	if (n > pow2 - 20) {
		n += 30;
	}

	/* Now we have n far enough from powers of 2. To make
	n more random (especially, if it was not near
	a power of 2), we then multiply it by a random number. */

80
	n = (ulint) ((double) n * UT_RANDOM_3);
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

	for (;; n++) {
		i = 2;
		while (i * i <= n) {
			if (n % i == 0) {
				goto next_n;
			}
			i++;
		}

		/* Found a prime */
		break;
next_n:		;
	}

	return(n);
}