mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
pgbench: Change terminology from "threshold" to "parameter".
Per a recommendation from Tomas Vondra, it's more helpful to refer to the value that determines how skewed a Gaussian or exponential distribution is as a parameter rather than a threshold. Since it's not quite too late to get this right in 9.5, where it was introduced, back-patch this. Most of the patch changes only comments and documentation, but a few pgbench messages are altered to match. Fabien Coelho, reviewed by Michael Paquier and by me.
This commit is contained in:
@ -90,7 +90,7 @@ static int pthread_join(pthread_t th, void **thread_return);
|
||||
#define LOG_STEP_SECONDS 5 /* seconds between log messages */
|
||||
#define DEFAULT_NXACTS 10 /* default nxacts */
|
||||
|
||||
#define MIN_GAUSSIAN_THRESHOLD 2.0 /* minimum threshold for gauss */
|
||||
#define MIN_GAUSSIAN_PARAM 2.0 /* minimum parameter for gauss */
|
||||
|
||||
int nxacts = 0; /* number of transactions per client */
|
||||
int duration = 0; /* duration in seconds */
|
||||
@ -488,47 +488,47 @@ getrand(TState *thread, int64 min, int64 max)
|
||||
|
||||
/*
|
||||
* random number generator: exponential distribution from min to max inclusive.
|
||||
* the threshold is so that the density of probability for the last cut-off max
|
||||
* value is exp(-threshold).
|
||||
* the parameter is so that the density of probability for the last cut-off max
|
||||
* value is exp(-parameter).
|
||||
*/
|
||||
static int64
|
||||
getExponentialRand(TState *thread, int64 min, int64 max, double threshold)
|
||||
getExponentialRand(TState *thread, int64 min, int64 max, double parameter)
|
||||
{
|
||||
double cut,
|
||||
uniform,
|
||||
rand;
|
||||
|
||||
Assert(threshold > 0.0);
|
||||
cut = exp(-threshold);
|
||||
Assert(parameter > 0.0);
|
||||
cut = exp(-parameter);
|
||||
/* erand in [0, 1), uniform in (0, 1] */
|
||||
uniform = 1.0 - pg_erand48(thread->random_state);
|
||||
|
||||
/*
|
||||
* inner expresion in (cut, 1] (if threshold > 0), rand in [0, 1)
|
||||
* inner expresion in (cut, 1] (if parameter > 0), rand in [0, 1)
|
||||
*/
|
||||
Assert((1.0 - cut) != 0.0);
|
||||
rand = -log(cut + (1.0 - cut) * uniform) / threshold;
|
||||
rand = -log(cut + (1.0 - cut) * uniform) / parameter;
|
||||
/* return int64 random number within between min and max */
|
||||
return min + (int64) ((max - min + 1) * rand);
|
||||
}
|
||||
|
||||
/* random number generator: gaussian distribution from min to max inclusive */
|
||||
static int64
|
||||
getGaussianRand(TState *thread, int64 min, int64 max, double threshold)
|
||||
getGaussianRand(TState *thread, int64 min, int64 max, double parameter)
|
||||
{
|
||||
double stdev;
|
||||
double rand;
|
||||
|
||||
/*
|
||||
* Get user specified random number from this loop, with -threshold <
|
||||
* stdev <= threshold
|
||||
* Get user specified random number from this loop,
|
||||
* with -parameter < stdev <= parameter
|
||||
*
|
||||
* This loop is executed until the number is in the expected range.
|
||||
*
|
||||
* As the minimum threshold is 2.0, the probability of looping is low:
|
||||
* As the minimum parameter is 2.0, the probability of looping is low:
|
||||
* sqrt(-2 ln(r)) <= 2 => r >= e^{-2} ~ 0.135, then when taking the
|
||||
* average sinus multiplier as 2/pi, we have a 8.6% looping probability in
|
||||
* the worst case. For a 5.0 threshold value, the looping probability is
|
||||
* the worst case. For a parameter value of 5.0, the looping probability is
|
||||
* about e^{-5} * 2 / pi ~ 0.43%.
|
||||
*/
|
||||
do
|
||||
@ -553,10 +553,10 @@ getGaussianRand(TState *thread, int64 min, int64 max, double threshold)
|
||||
* over.
|
||||
*/
|
||||
}
|
||||
while (stdev < -threshold || stdev >= threshold);
|
||||
while (stdev < -parameter || stdev >= parameter);
|
||||
|
||||
/* stdev is in [-threshold, threshold), normalization to [0,1) */
|
||||
rand = (stdev + threshold) / (threshold * 2.0);
|
||||
/* stdev is in [-parameter, parameter), normalization to [0,1) */
|
||||
rand = (stdev + parameter) / (parameter * 2.0);
|
||||
|
||||
/* return int64 random number within between min and max */
|
||||
return min + (int64) ((max - min + 1) * rand);
|
||||
@ -1483,7 +1483,7 @@ top:
|
||||
char *var;
|
||||
int64 min,
|
||||
max;
|
||||
double threshold = 0;
|
||||
double parameter = 0;
|
||||
char res[64];
|
||||
|
||||
if (*argv[2] == ':')
|
||||
@ -1554,41 +1554,49 @@ top:
|
||||
{
|
||||
if ((var = getVariable(st, argv[5] + 1)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid threshold number: \"%s\"\n",
|
||||
fprintf(stderr, "%s: invalid parameter: \"%s\"\n",
|
||||
argv[0], argv[5]);
|
||||
st->ecnt++;
|
||||
return true;
|
||||
}
|
||||
threshold = strtod(var, NULL);
|
||||
parameter = strtod(var, NULL);
|
||||
}
|
||||
else
|
||||
threshold = strtod(argv[5], NULL);
|
||||
parameter = strtod(argv[5], NULL);
|
||||
|
||||
if (pg_strcasecmp(argv[4], "gaussian") == 0)
|
||||
{
|
||||
if (threshold < MIN_GAUSSIAN_THRESHOLD)
|
||||
if (parameter < MIN_GAUSSIAN_PARAM)
|
||||
{
|
||||
fprintf(stderr, "gaussian threshold must be at least %f (not \"%s\")\n", MIN_GAUSSIAN_THRESHOLD, argv[5]);
|
||||
fprintf(stderr, "gaussian parameter must be at least %f (not \"%s\")\n", MIN_GAUSSIAN_PARAM, argv[5]);
|
||||
st->ecnt++;
|
||||
return true;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n", min, max, getGaussianRand(thread, min, max, threshold));
|
||||
printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n",
|
||||
min, max,
|
||||
getGaussianRand(thread, min, max, parameter));
|
||||
#endif
|
||||
snprintf(res, sizeof(res), INT64_FORMAT, getGaussianRand(thread, min, max, threshold));
|
||||
snprintf(res, sizeof(res), INT64_FORMAT,
|
||||
getGaussianRand(thread, min, max, parameter));
|
||||
}
|
||||
else if (pg_strcasecmp(argv[4], "exponential") == 0)
|
||||
{
|
||||
if (threshold <= 0.0)
|
||||
if (parameter <= 0.0)
|
||||
{
|
||||
fprintf(stderr, "exponential threshold must be greater than zero (not \"%s\")\n", argv[5]);
|
||||
fprintf(stderr,
|
||||
"exponential parameter must be greater than zero (not \"%s\")\n",
|
||||
argv[5]);
|
||||
st->ecnt++;
|
||||
return true;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n", min, max, getExponentialRand(thread, min, max, threshold));
|
||||
printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n",
|
||||
min, max,
|
||||
getExponentialRand(thread, min, max, parameter));
|
||||
#endif
|
||||
snprintf(res, sizeof(res), INT64_FORMAT, getExponentialRand(thread, min, max, threshold));
|
||||
snprintf(res, sizeof(res), INT64_FORMAT,
|
||||
getExponentialRand(thread, min, max, parameter));
|
||||
}
|
||||
}
|
||||
else /* this means an error somewhere in the parsing phase... */
|
||||
@ -2282,8 +2290,9 @@ process_commands(char *buf, const char *source, const int lineno)
|
||||
if (pg_strcasecmp(my_commands->argv[0], "setrandom") == 0)
|
||||
{
|
||||
/*
|
||||
* parsing: \setrandom variable min max [uniform] \setrandom
|
||||
* variable min max (gaussian|exponential) threshold
|
||||
* parsing:
|
||||
* \setrandom variable min max [uniform]
|
||||
* \setrandom variable min max (gaussian|exponential) parameter
|
||||
*/
|
||||
|
||||
if (my_commands->argc < 4)
|
||||
@ -2308,7 +2317,7 @@ process_commands(char *buf, const char *source, const int lineno)
|
||||
if (my_commands->argc < 6)
|
||||
{
|
||||
syntax_error(source, lineno, my_commands->line, my_commands->argv[0],
|
||||
"missing threshold argument", my_commands->argv[4], -1);
|
||||
"missing parameter", my_commands->argv[4], -1);
|
||||
}
|
||||
else if (my_commands->argc > 6)
|
||||
{
|
||||
|
Reference in New Issue
Block a user