Hi,

(2014/03/04 17:42), KONDO Mitsumasa wrote:> (2014/03/04 17:28), Fabien COELHO 
wrote:
>>> OK. I'm not sure which idia is the best. So I wait for comments in 
community:)
>> Hmmm. Maybe you can do what Tom voted for, he is the committer:-)
> Yeah, but he might change his mind by our disscuttion. So I wait untill 
tomorrow,
> and if nothing to comment, I will start to fix what Tom voted for.
I create the patch which is fixed UI. If we agree with this interface,
I also start to fix the document.


New "\setrandom" interface is here.
  \setrandom var min max [gaussian threshold | exponential threshold]

Attached patch realizes this interface, but it has little bit ugly codeing in executeStatement() and process_commands().. That is under following.
if(argc == 4)
{
... /* uniform */
}
else if (argv[4]== gaussian or exponential)
{
... /* gaussian or exponential */
}
else
{
... /* uniform with extra argments */
}

It is beacause pgbench custom script allows extra comments or extra argument in its file. For example, under following cases are no problem case.
  \setrandom var min max #hoge   --> uniform random
  \setrandom var min max #hoge1 #hoge2  --> uniform random
  \setrandom var min max gaussian threshold #hoge  -->gaussian random

And other cases are classified under following.
  \setrandom var min max gaussian #hoge --> uniform
  \setrandom var min max max2 gaussian threshold --> uniform
  \setrandom var min gaussian #hoge --> ERROR

However, if we wrong grammer in pgbench custom script,
pgbench outputs error log on user terminal. So I think it is especially no 
problem.

What do you think?

Regards,
--
Mitsumasa KONDO
NTT Open Source Software Center
*** a/contrib/pgbench/pgbench.c
--- b/contrib/pgbench/pgbench.c
***************
*** 98,103 **** static int	pthread_join(pthread_t th, void **thread_return);
--- 98,106 ----
  #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_EXPONENTIAL_THRESHOLD	2.0	/* minimum threshold for exp */
+ 
  int			nxacts = 0;			/* number of transactions per client */
  int			duration = 0;		/* duration in seconds */
  
***************
*** 169,174 **** bool		is_connect;			/* establish connection for each transaction */
--- 172,185 ----
  bool		is_latencies;		/* report per-command latencies */
  int			main_pid;			/* main process id used in log filename */
  
+ /* gaussian distribution tests: */
+ double		stdev_threshold;   /* standard deviation threshold */
+ bool        use_gaussian = false;
+ 
+ /* exponential distribution tests: */
+ double		exp_threshold;   /* threshold for exponential */
+ bool		use_exponential = false;
+ 
  char	   *pghost = "";
  char	   *pgport = "";
  char	   *login = NULL;
***************
*** 330,335 **** static char *select_only = {
--- 341,428 ----
  	"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
  };
  
+ /* --exponential case */
+ static char *exponential_tpc_b = {
+ 	"\\set nbranches " CppAsString2(nbranches) " * :scale\n"
+ 	"\\set ntellers " CppAsString2(ntellers) " * :scale\n"
+ 	"\\set naccounts " CppAsString2(naccounts) " * :scale\n"
+ 	"\\setrandom aid 1 :naccounts exponential :exp_threshold\n"
+ 	"\\setrandom bid 1 :nbranches\n"
+ 	"\\setrandom tid 1 :ntellers\n"
+ 	"\\setrandom delta -5000 5000\n"
+ 	"BEGIN;\n"
+ 	"UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
+ 	"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+ 	"UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
+ 	"UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
+ 	"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
+ 	"END;\n"
+ };
+ 
+ /* --exponential with -N case */
+ static char *exponential_simple_update = {
+ 	"\\set nbranches " CppAsString2(nbranches) " * :scale\n"
+ 	"\\set ntellers " CppAsString2(ntellers) " * :scale\n"
+ 	"\\set naccounts " CppAsString2(naccounts) " * :scale\n"
+ 	"\\setrandom aid 1 :naccounts exponential :exp_threshold\n"
+ 	"\\setrandom bid 1 :nbranches\n"
+ 	"\\setrandom tid 1 :ntellers\n"
+ 	"\\setrandom delta -5000 5000\n"
+ 	"BEGIN;\n"
+ 	"UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
+ 	"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+ 	"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
+ 	"END;\n"
+ };
+ 
+ /* --exponential with -S case */
+ static char *exponential_select_only = {
+ 	"\\set naccounts " CppAsString2(naccounts) " * :scale\n"
+ 	"\\setrandom aid 1 :naccounts exponential :exp_threshold\n"
+ 	"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+ };
+ 
+ /* --gaussian case */
+ static char *gaussian_tpc_b = {
+ 	"\\set nbranches " CppAsString2(nbranches) " * :scale\n"
+ 	"\\set ntellers " CppAsString2(ntellers) " * :scale\n"
+ 	"\\set naccounts " CppAsString2(naccounts) " * :scale\n"
+ 	"\\setrandom aid 1 :naccounts gaussian :stdev_threshold\n"
+ 	"\\setrandom bid 1 :nbranches\n"
+ 	"\\setrandom tid 1 :ntellers\n"
+ 	"\\setrandom delta -5000 5000\n"
+ 	"BEGIN;\n"
+ 	"UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
+ 	"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+ 	"UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
+ 	"UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
+ 	"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
+ 	"END;\n"
+ };
+ 
+ /* --gaussian with -N case */
+ static char *gaussian_simple_update = {
+ 	"\\set nbranches " CppAsString2(nbranches) " * :scale\n"
+ 	"\\set ntellers " CppAsString2(ntellers) " * :scale\n"
+ 	"\\set naccounts " CppAsString2(naccounts) " * :scale\n"
+ 	"\\setrandom aid 1 :naccounts gaussian :stdev_threshold\n"
+ 	"\\setrandom bid 1 :nbranches\n"
+ 	"\\setrandom tid 1 :ntellers\n"
+ 	"\\setrandom delta -5000 5000\n"
+ 	"BEGIN;\n"
+ 	"UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
+ 	"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+ 	"INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
+ 	"END;\n"
+ };
+ 
+ /* --gaussian with -S case */
+ static char *gaussian_select_only = {
+ 	"\\set naccounts " CppAsString2(naccounts) " * :scale\n"
+ 	"\\setrandom aid 1 :naccounts gaussian :stdev_threshold\n"
+ 	"SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
+ };
+ 
  /* Function prototypes */
  static void setalarm(int seconds);
  static void *threadRun(void *arg);
***************
*** 373,378 **** usage(void)
--- 466,473 ----
  		   "  -v, --vacuum-all         vacuum all four standard tables before tests\n"
  		   "  --aggregate-interval=NUM aggregate data over NUM seconds\n"
  		   "  --sampling-rate=NUM      fraction of transactions to log (e.g. 0.01 for 1%%)\n"
+ 		   "  --exponential=NUM        exponential distribution with NUM threshold parameter\n"
+ 		   "  --gaussian=NUM           gaussian distribution with NUM standard deviation threshold\n"
  		   "\nCommon options:\n"
  		   "  -d, --debug              print debugging output\n"
  		   "  -h, --host=HOSTNAME      database server host or socket directory\n"
***************
*** 469,474 **** getrand(TState *thread, int64 min, int64 max)
--- 564,642 ----
  	return min + (int64) ((max - min + 1) * pg_erand48(thread->random_state));
  }
  
+ /* random number generator: exponential distribution from min to max inclusive */
+ static int64
+ getExponentialrand(TState *thread, int64 min, int64 max, double exp_threshold)
+ {
+ 	double		rand;
+ 
+ 	/*
+ 	 * Get user specified random number in this loop. This loop is executed until
+ 	 * the number in the expected range. As the minimum threshold is 2.0, the
+ 	 * probability of a retry is at worst 13.5%  as - ln(0.135) ~ 2.0 ;
+ 	 * For a 5.0 threshold, it is about e^{-5} ~ 0.7%.
+ 	 */
+ 	do
+ 	{
+ 		/* as pg_erand48 is in [0, 1), uniform is in (0, 1] */
+ 		double uniform = 1.0 - pg_erand48(thread->random_state);
+ 		/* rand is in [0 LARGE) */
+ 		rand = - log(uniform);
+ 	} while (rand >= exp_threshold);
+ 
+ 	/* rand in [0, exp_threshold), normalized to [0,1) */
+ 	rand /= exp_threshold;
+ 
+ 	/* 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 stdev_threshold)
+ {
+ 	double		stdev;
+ 	double		rand;
+ 
+ 	/*
+ 	 * Get user specified random number from this loop, with
+ 	 *    -stdev_threshold < stdev <= stdev_threshold
+ 	 *
+ 	 * 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:
+ 	 * 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 proability
+ 	 * is about e^{-5} * 2 / pi ~ 0.43%.
+ 	 */
+ 	do
+ 	{
+ 		/*
+ 		 * pg_erand48 generates [0,1), but for the basic version of the
+ 		 * Box-Muller transform the two uniformly distributed random numbers
+ 		 * are expected in (0, 1] (see http://en.wikipedia.org/wiki/Box_muller)
+ 		 */
+ 		double rand1 = 1.0 - pg_erand48(thread->random_state);
+ 		double rand2 = 1.0 - pg_erand48(thread->random_state);
+ 
+ 		/* Box-Muller basic form transform */
+ 		double var_sqrt = sqrt(-2.0 * log(rand1));
+ 		stdev = var_sqrt * sin(2.0 * M_PI * rand2);
+ 
+ 		/* we may try with cos, but there may be a bias induced if the previous
+ 		 * value fails the test? To be on the safe side, let us try over.
+ 		 */
+ 	}
+ 	while (stdev < -stdev_threshold || stdev >= stdev_threshold);
+ 
+ 	/* stdev is in [-threshold, threshold), normalization to [0,1) */
+ 	rand = (stdev + stdev_threshold) / (stdev_threshold * 2.0);
+ 
+ 	/* return int64 random number within between min and max */
+ 	return min + (int64)((max - min + 1) * rand);
+ }
+ 
  /* call PQexec() and exit() on failure */
  static void
  executeStatement(PGconn *con, const char *sql)
***************
*** 1312,1317 **** top:
--- 1480,1486 ----
  			char	   *var;
  			int64		min,
  						max;
+ 			double		threshold = 0;
  			char		res[64];
  
  			if (*argv[2] == ':')
***************
*** 1357,1367 **** top:
  			}
  
  			/*
! 			 * getrand() needs to be able to subtract max from min and add one
! 			 * to the result without overflowing.  Since we know max > min, we
! 			 * can detect overflow just by checking for a negative result. But
! 			 * we must check both that the subtraction doesn't overflow, and
! 			 * that adding one to the result doesn't overflow either.
  			 */
  			if (max - min < 0 || (max - min) + 1 < 0)
  			{
--- 1526,1536 ----
  			}
  
  			/*
! 			 * Generate random number functions need to be able to subtract
! 			 * max from min and add one to the result without overflowing.
! 			 * Since we know max > min, we can detect overflow just by checking
! 			 * for a negative result. But we must check both that the subtraction
! 			 * doesn't overflow, and that adding one to the result doesn't overflow either.
  			 */
  			if (max - min < 0 || (max - min) + 1 < 0)
  			{
***************
*** 1370,1379 **** top:
  				return true;
  			}
  
  #ifdef DEBUG
! 			printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n", min, max, getrand(thread, min, max));
  #endif
! 			snprintf(res, sizeof(res), INT64_FORMAT, getrand(thread, min, max));
  
  			if (!putVariable(st, argv[0], argv[1], res))
  			{
--- 1539,1601 ----
  				return true;
  			}
  
+ 			if (argc == 4) /* uniform */
+ 			{
  #ifdef DEBUG
! 				printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n", min, max, getrand(thread, min, max));
  #endif
! 				snprintf(res, sizeof(res), INT64_FORMAT, getrand(thread, min, max));
! 			}
! 			else if ((pg_strcasecmp(argv[4], "gaussian") == 0) ||
! 				 (pg_strcasecmp(argv[4], "exponential") == 0))
! 			{
! 				if (*argv[5] == ':')
! 				{
! 					if ((var = getVariable(st, argv[5] + 1)) == NULL)
! 					{
! 						fprintf(stderr, "%s: invalid threshold number %s\n", argv[0], argv[5]);
! 						st->ecnt++;
! 						return true;
! 					}
! 					threshold = strtod(var, NULL);
! 				}
! 				else
! 					threshold = strtod(argv[5], NULL);
! 
! 				if (pg_strcasecmp(argv[4], "gaussian") == 0)
! 				{
! 					if (threshold < MIN_GAUSSIAN_THRESHOLD)
! 					{
! 						fprintf(stderr, "%s: gaussian threshold must be more than %f\n,", argv[5], MIN_GAUSSIAN_THRESHOLD);
! 						st->ecnt++;
! 						return true;
! 					}
! #ifdef DEBUG
! 					printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n", min, max, getGaussianrand(thread, min, max, threshold));
! #endif
! 					snprintf(res, sizeof(res), INT64_FORMAT, getGaussianrand(thread, min, max, threshold));
! 				}
! 				else if (pg_strcasecmp(argv[4], "exponential") == 0)
! 				{
! 					if (threshold < MIN_EXPONENTIAL_THRESHOLD)
! 					{
! 						fprintf(stderr, "%s: exponential threshold must be more than %f\n,", argv[5], MIN_EXPONENTIAL_THRESHOLD);
! 						st->ecnt++;
! 						return true;
! 					}
! #ifdef DEBUG
! 					printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n", min, max, getExponentialrand(thread, min, max, threshold));
! #endif
! 					snprintf(res, sizeof(res), INT64_FORMAT, getExponentialrand(thread, min, max, threshold));
! 				}
! 			}
! 			else /* uniform with extra arguments */
! 			{
! #ifdef DEBUG
! 				printf("min: " INT64_FORMAT " max: " INT64_FORMAT " random: " INT64_FORMAT "\n", min, max, getrand(thread, min, max));
! #endif
! 				snprintf(res, sizeof(res), INT64_FORMAT, getrand(thread, min, max));
! 			}
  
  			if (!putVariable(st, argv[0], argv[1], res))
  			{
***************
*** 1903,1911 **** process_commands(char *buf)
  				exit(1);
  			}
  
! 			for (j = 4; j < my_commands->argc; j++)
! 				fprintf(stderr, "%s: extra argument \"%s\" ignored\n",
! 						my_commands->argv[0], my_commands->argv[j]);
  		}
  		else if (pg_strcasecmp(my_commands->argv[0], "set") == 0)
  		{
--- 2125,2153 ----
  				exit(1);
  			}
  
! 			if (my_commands->argc == 4) /* uniform */
! 			{
! 				/* nothing to do */
! 			}
! 			else if ((pg_strcasecmp(my_commands->argv[4], "gaussian") == 0) ||
! 				 (pg_strcasecmp(my_commands->argv[4], "exponential") == 0))
! 			{
! 				if (my_commands->argc < 6)
! 				{
! 					fprintf(stderr, "%s(%s): missing argument\n", my_commands->argv[0], my_commands->argv[4]);
! 					exit(1);
! 				}
! 
! 				for (j = 6; j < my_commands->argc; j++)
! 					fprintf(stderr, "%s(%s): extra argument \"%s\" ignored\n",
! 							my_commands->argv[0], my_commands->argv[4], my_commands->argv[j]);
! 			}
! 			else /* uniform with extra argument */
! 			{
! 				for (j = 4; j < my_commands->argc; j++)
! 					fprintf(stderr, "%s(uniform): extra argument \"%s\" ignored\n",
! 							my_commands->argv[0], my_commands->argv[j]);
! 			}
  		}
  		else if (pg_strcasecmp(my_commands->argv[0], "set") == 0)
  		{
***************
*** 2180,2195 **** printResults(int ttype, int normal_xacts, int nclients,
  						(INSTR_TIME_GET_DOUBLE(conn_total_time) / nthreads));
  
  	if (ttype == 0)
! 		s = "TPC-B (sort of)";
  	else if (ttype == 2)
! 		s = "Update only pgbench_accounts";
  	else if (ttype == 1)
! 		s = "SELECT only";
  	else
  		s = "Custom query";
  
  	printf("transaction type: %s\n", s);
  	printf("scaling factor: %d\n", scale);
  	printf("query mode: %s\n", QUERYMODE[querymode]);
  	printf("number of clients: %d\n", nclients);
  	printf("number of threads: %d\n", nthreads);
--- 2422,2478 ----
  						(INSTR_TIME_GET_DOUBLE(conn_total_time) / nthreads));
  
  	if (ttype == 0)
! 	{
! 		if (use_gaussian)
! 			s = "Gaussian distribution TPC-B (sort of)";
! 		else if (use_exponential)
! 			s = "Exponential distribution TPC-B (sort of)";
! 		else
! 			s = "TPC-B (sort of)";
! 	}
  	else if (ttype == 2)
! 	{
! 		if (use_gaussian)
! 			s = "Gaussian distribution update only pgbench_accounts";
! 		else if (use_exponential)
! 			s = "Exponential distribution update only pgbench_accounts";
! 		else
! 			s = "Update only pgbench_accounts";
! 	}
  	else if (ttype == 1)
! 	{
! 		if (use_gaussian)
! 			s = "Gaussian distribution SELECT only";
! 		else if (use_exponential)
! 			s = "Exponential distribution SELECT only";
! 		else
! 			s = "SELECT only";
! 	}
  	else
  		s = "Custom query";
  
  	printf("transaction type: %s\n", s);
  	printf("scaling factor: %d\n", scale);
+ 
+ 	/* output in gaussian distribution benchmark */
+ 	if (use_gaussian)
+ 	{
+ 		printf("standard deviation threshold: %.5f\n", stdev_threshold);
+ 		printf("access probability of top 20%%, 10%% and 5%% records: %.5f %.5f %.5f\n",
+ 			(double) ((erf (stdev_threshold * 0.2 / sqrt(2.0))) / (erf (stdev_threshold / sqrt(2.0)))),
+ 			(double) ((erf (stdev_threshold * 0.1 / sqrt(2.0))) / (erf (stdev_threshold / sqrt(2.0)))),
+ 			(double) ((erf (stdev_threshold * 0.05 / sqrt(2.0))) / (erf (stdev_threshold / sqrt(2.0)))));
+ 	}
+ 	/* output in exponential distribution benchmark  */
+ 	else if (use_exponential)
+ 	{
+ 		printf("exponential threshold: %.5f\n", exp_threshold);
+ 		printf("access probability of top 20%%, 10%% and 5%% records: %.5f %.5f %.5f\n",
+ 			(double) (-exp(-exp_threshold * 0.2) + 1),
+ 			(double) (-exp(-exp_threshold * 0.1) + 1),
+ 			(double) (-exp(-exp_threshold * 0.05) + 1));
+ 	}
+ 
  	printf("query mode: %s\n", QUERYMODE[querymode]);
  	printf("number of clients: %d\n", nclients);
  	printf("number of threads: %d\n", nthreads);
***************
*** 2319,2324 **** main(int argc, char **argv)
--- 2602,2609 ----
  		{"unlogged-tables", no_argument, &unlogged_tables, 1},
  		{"sampling-rate", required_argument, NULL, 4},
  		{"aggregate-interval", required_argument, NULL, 5},
+ 		{"gaussian", required_argument, NULL, 6},
+ 		{"exponential", required_argument, NULL, 7},
  		{"rate", required_argument, NULL, 'R'},
  		{NULL, 0, NULL, 0}
  	};
***************
*** 2598,2605 **** main(int argc, char **argv)
  				}
  #endif
  				break;
  			default:
! 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
  				exit(1);
  				break;
  		}
--- 2883,2910 ----
  				}
  #endif
  				break;
+ 			case 6:
+ 				use_gaussian = true;
+ 				stdev_threshold = atof(optarg);
+ 				if(stdev_threshold < MIN_GAUSSIAN_THRESHOLD)
+ 				{
+ 					fprintf(stderr, "--gaussian=NUM must be more than %f: %f\n",
+ 							MIN_GAUSSIAN_THRESHOLD, stdev_threshold);
+ 					exit(1);
+ 				}
+ 				break;
+ 			case 7:
+ 				use_exponential = true;
+ 				exp_threshold = atof(optarg);
+ 				if(exp_threshold < MIN_EXPONENTIAL_THRESHOLD)
+ 				{
+ 					fprintf(stderr,	"--exponential=NUM must be more than %f: %f\n",
+ 							MIN_EXPONENTIAL_THRESHOLD, exp_threshold);
+ 					exit(1);
+ 				}
+ 				break;
  			default:
! 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),	progname);
  				exit(1);
  				break;
  		}
***************
*** 2795,2800 **** main(int argc, char **argv)
--- 3100,3127 ----
  		}
  	}
  
+ 	/* set :stdev_threshold variable */
+ 	if(getVariable(&state[0], "stdev_threshold") == NULL)
+ 	{
+ 		snprintf(val, sizeof(val), "%lf", stdev_threshold);
+ 		for (i = 0; i < nclients; i++)
+ 		{
+ 			if (!putVariable(&state[i], "startup", "stdev_threshold", val))
+ 				exit(1);
+ 		}
+ 	}
+ 
+ 	/* set :exp_threshold variable */
+ 	if(getVariable(&state[0], "exp_threshold") == NULL)
+ 	{
+ 		snprintf(val, sizeof(val), "%lf", exp_threshold);
+ 		for (i = 0; i < nclients; i++)
+ 		{
+ 			if (!putVariable(&state[i], "startup", "exp_threshold", val))
+ 				exit(1);
+ 		}
+ 	}
+ 
  	if (!is_no_vacuum)
  	{
  		fprintf(stderr, "starting vacuum...");
***************
*** 2820,2836 **** main(int argc, char **argv)
  	switch (ttype)
  	{
  		case 0:
! 			sql_files[0] = process_builtin(tpc_b);
  			num_files = 1;
  			break;
  
  		case 1:
! 			sql_files[0] = process_builtin(select_only);
  			num_files = 1;
  			break;
  
  		case 2:
! 			sql_files[0] = process_builtin(simple_update);
  			num_files = 1;
  			break;
  
--- 3147,3178 ----
  	switch (ttype)
  	{
  		case 0:
! 			if (use_gaussian)
! 				sql_files[0] = process_builtin(gaussian_tpc_b);
! 			else if (use_exponential)
! 				sql_files[0] = process_builtin(exponential_tpc_b);
! 			else
! 				sql_files[0] = process_builtin(tpc_b);
  			num_files = 1;
  			break;
  
  		case 1:
! 			if (use_gaussian)
! 				sql_files[0] = process_builtin(gaussian_select_only);
! 			else if (use_exponential)
! 				sql_files[0] = process_builtin(exponential_select_only);
! 			else
! 				sql_files[0] = process_builtin(select_only);
  			num_files = 1;
  			break;
  
  		case 2:
! 			if (use_gaussian)
! 				sql_files[0] = process_builtin(gaussian_simple_update);
! 			else if (use_exponential)
! 				sql_files[0] = process_builtin(exponential_simple_update);
! 			else
! 				sql_files[0] = process_builtin(simple_update);
  			num_files = 1;
  			break;
  
*** a/doc/src/sgml/pgbench.sgml
--- b/doc/src/sgml/pgbench.sgml
***************
*** 307,312 **** pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
--- 307,328 ----
       </varlistentry>
  
       <varlistentry>
+       <term><option>--exponential</option><replaceable>deviation threshold</></term>
+       <listitem>
+        <para>
+          Deviation threshold for the exponential distribution pgbench test.
+          This threshold controls the distribution of accesses on the
+          <structname>pgbench_accounts</> table.
+          The larger the deviation threshold, the more records at the beginning
+          are accessed. The smaller the deviation threshold, the smoother the access
+          pattern distribution. The deviation threshold must be more than 2 for
+          internal performance. When set, this option applies to all test variants
+          (<option>-N</> for skipping updates, or <option>-S</> for selects).
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
        <term><option>-f</option> <replaceable>filename</></term>
        <term><option>--file=</option><replaceable>filename</></term>
        <listitem>
***************
*** 320,325 **** pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
--- 336,357 ----
       </varlistentry>
  
       <varlistentry>
+       <term><option>--gaussian</option><replaceable>standard deviation threshold</></term>
+       <listitem>
+        <para>
+          Deviation threshold for the Gaussian distribution pgbench test.
+          This threshold controls the distribution of accesses on the
+          <structname>pgbench_accounts</> table.
+          The larger the deviation threshold, the more records in the middle of the table
+          are accessed. The smaller the deviation threshold, the smoother the access
+          pattern distribution. The deviation threshold must be more than 2 for
+          internal performance. When set, this option applies to all test variants
+          (<option>-N</> for skipping updates, or <option>-S</> for selects).
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
        <term><option>-j</option> <replaceable>threads</></term>
        <term><option>--jobs=</option><replaceable>threads</></term>
        <listitem>
***************
*** 770,775 **** pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
--- 802,860 ----
  
     <varlistentry>
      <term>
+      <literal>\setgaussian <replaceable>varname</> <replaceable>min</> <replaceable>max</> <replaceable>
+      standard deviation threshold</literal>
+     </term>
+ 
+     <listitem>
+      <para>
+       Set variable <replaceable>varname</> to a gaussian random integer value
+       between <replaceable>min</> and <replaceable>max</> bounds inclusive.
+       Each bound can be either an integer constant or a
+       <literal>:</><replaceable>variablename</> reference to a variable
+       having an integer value. The standard deviation threshold controls
+       the distribution pattern. The larger the threshold, the more frequent
+       values close to the middle of the interval are drawn. The threshold is
+       the deviation for the <replaceable>min</> and <replaceable>max</> bounds.
+       The minimum threshold is 2.0, for performance.
+      </para>
+ 
+      <para>
+       Example:
+ <programlisting>
+ \setgaussian aid 1 :naccounts 5
+ </programlisting></para>
+     </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
+        <term>
+         <literal>\setexponential <replaceable>varname</> <replaceable>min</> <replaceable>max</> <replaceable>
+         deviation threshold</literal>
+        </term>
+ 
+     <listitem>
+      <para>
+       Set variable <replaceable>varname</> to an exponential random integer value
+       between <replaceable>min</> and <replaceable>max</> bounds inclusive.
+       Each bound can be either an integer constant or a
+       <literal>:</><replaceable>variablename</> reference to a variable
+       having an integer value. The deviation threshold controls the distribution
+       pattern: the larger the deviation threshold, the more frequent values
+       close to <replaceable>min</> are drawn.
+       The minimum threshold is 2.0, for performance.
+      </para>
+ 
+      <para>
+       Example:
+ <programlisting>
+ \setexponential aid 1 :naccounts 5
+ </programlisting></para>
+      </listitem>
+    </varlistentry>
+ 
+    <varlistentry>
+     <term>
       <literal>\sleep <replaceable>number</> [ us | ms | s ]</literal>
      </term>
  
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to