Hello Michaƫl,

Two rebase attached.

 - 15-e: prefix selection for -b

-               if (strncmp(builtin_script[i].name, name,
-                                       strlen(builtin_script[i].name)) == 0)
+               if (strncmp(builtin_script[i].name, name, len) == 0)

I agree with Alvaro here: this should remain unchanged. It seems to be
a rebase mistake.

I do not understand. I tested it and it works as expected. If I put the above strlen instead the suffix detection does not work:


 fabien@sto:bin/pgbench> git diff
 diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
 index 783cbf9..0c33012 100644
 --- a/src/bin/pgbench/pgbench.c
 +++ b/src/bin/pgbench/pgbench.c
 @@ -2684,7 +2684,7 @@ findBuiltin(const char *name, char **desc)

         for (i = 0; i < N_BUILTIN; i++)
         {
 -               if (strncmp(builtin_script[i].name, name, len) == 0)
 +               if (strncmp(builtin_script[i].name, name, 
strlen(builtin_script[i].name)) == 0)
                 {
                         *desc = builtin_script[i].desc;
                         commands = builtin_script[i].commands;


 ./pgbench -b t
 no builtin script found for name "t"
 Available builtin scripts:
         tpcb-like
         simple-update
         select-only

Indeed, then it can only match if the provided "name" is as long as the recorded len. The point of the "suffix" selection is to align to the short supplied string.

--
Fabien.
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index ade1b53..ca3e158 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -262,11 +262,13 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
 
     <variablelist>
      <varlistentry>
-      <term><option>-b</> <replaceable>scriptname</></term>
-      <term><option>--builtin</> <replaceable>scriptname</></term>
+      <term><option>-b</> <replaceable>scriptname[@weight]</></term>
+      <term><option>--builtin</> <replaceable>scriptname[@weight]</></term>
       <listitem>
        <para>
         Add the specified builtin script to the list of executed scripts.
+        An optional integer weight after <literal>@</> allows to adjust the
+        probability of drawing the test.
         Available builtin scripts are: <literal>tpcb-like</>,
         <literal>simple-update</> and <literal>select-only</>.
         With special name <literal>list</>, show the list of builtin scripts
@@ -321,12 +323,14 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
      </varlistentry>
 
      <varlistentry>
-      <term><option>-f</> <replaceable>filename</></term>
-      <term><option>--file=</><replaceable>filename</></term>
+      <term><option>-f</> <replaceable>filename[@weight]</></term>
+      <term><option>--file=</><replaceable>filename[@weight]</></term>
       <listitem>
        <para>
         Add a transaction script read from <replaceable>filename</> to
         the list of executed scripts.
+        An optional integer weight after <literal>@</> allows to adjust the
+        probability of drawing the test.
         See below for details.
        </para>
       </listitem>
@@ -689,6 +693,9 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
    Pgbench executes test scripts chosen randomly from a specified list.
    They include built-in scripts with <option>-b</> and
    user-provided custom scripts with <option>-f</>.
+   Each script may be given a relative weight specified after a
+   <literal>@</> so as to change its drawing probability.
+   The default weight is <literal>1</>.
  </para>
 
   <para>
@@ -1137,7 +1144,7 @@ number of transactions per client: 1000
 number of transactions actually processed: 10000/10000
 tps = 618.764555 (including connections establishing)
 tps = 622.977698 (excluding connections establishing)
-SQL script 1: &lt;builtin: TPC-B (sort of)&gt;
+SQL script 1, weight 1: &lt;builtin: TPC-B (sort of)&gt;
  - 10000 transactions (100.0% of total, tps = 618.764555)
  - latency average = 15.844 ms
  - latency stddev = 2.715 ms
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 7eb6a2d..5d24768 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -179,6 +179,8 @@ char	   *login = NULL;
 char	   *dbName;
 const char *progname;
 
+#define WSEP '@' /* weight separator */
+
 volatile bool timer_exceeded = false;	/* flag from signal handler */
 
 /* variable definitions */
@@ -299,11 +301,14 @@ typedef struct
 static struct
 {
 	const char *name;
+	int weight;
 	Command   **commands;
 	StatsData stats;
 }	sql_script[MAX_SCRIPTS];	/* SQL script files */
 static int	num_scripts;		/* number of scripts in sql_script[] */
 static int	num_commands = 0;	/* total number of Command structs */
+static int  total_weight = 0;
+
 static int	debug = 0;			/* debug flag */
 
 /* Define builtin test scripts */
@@ -389,9 +394,9 @@ usage(void)
 	 "  --tablespace=TABLESPACE  create tables in the specified tablespace\n"
 		   "  --unlogged-tables        create tables as unlogged tables\n"
 		   "\nOptions to select what to run:\n"
-		   "  -b, --builtin=NAME       add buitin script (use \"-b list\" to display\n"
-		   "                           available scripts)\n"
-		   "  -f, --file=FILENAME      add transaction script from FILENAME\n"
+		   "  -b, --builtin=NAME[@W]   add weighted buitin script (use \"-b list\"\n"
+		   "                           to display available scripts)\n"
+		   "  -f, --file=FILENAME[@W]  add weighted transaction script from FILENAME\n"
 		   "  -N, --skip-some-updates  skip updates of pgbench_tellers and pgbench_branches\n"
 		   "                           (same as \"-b simple-update\")\n"
 		   "  -S, --select-only        perform SELECT-only transactions\n"
@@ -1238,10 +1243,17 @@ clientDone(CState *st, bool ok)
 static int
 chooseScript(TState *thread)
 {
+	int i = 0, w = 0, wc;
+
 	if (num_scripts == 1)
 		return 0;
 
-	return getrand(thread, 0, num_scripts - 1);
+	wc = (int) getrand(thread, 0, total_weight - 1);
+	do {
+		w += sql_script[i++].weight;
+	} while (w <= wc);
+
+	return i - 1;
 }
 
 /* return false iff client should be disconnected */
@@ -2683,8 +2695,41 @@ findBuiltin(const char *name, char **desc)
 	exit(1);
 }
 
+/* Possiby truncate option and return weight */
+static int
+getWeight(char *option)
+{
+	char   *sep;
+	int		weight;
+
+	if ((sep = strrchr(option, WSEP)))
+	{
+		char *s;
+		*sep++ = '\0';
+
+		/* check that the weight is a positive integer */
+		s = sep;
+		while ('0' <= *s && *s <= '9')
+			s++;
+		if (*s != '\0' || s == sep)
+		{
+			/* empty or any other char */
+			fprintf(stderr,
+					"weight for script \"%s\" must be an integer, got \"%s\"\n",
+					option, sep);
+			exit(1);
+		}
+
+		weight = atoi(sep);
+	}
+	else
+		weight = 1;
+
+	return weight;
+}
+
 static void
-addScript(const char *name, Command **commands)
+addScript(const char *name, Command **commands, int weight)
 {
 	if (commands == NULL)
 	{
@@ -2699,6 +2744,7 @@ addScript(const char *name, Command **commands)
 	}
 
 	sql_script[num_scripts].name = name;
+	sql_script[num_scripts].weight = weight;
 	sql_script[num_scripts].commands = commands;
 	initStats(&sql_script[num_scripts].stats, 0.0);
 	num_scripts++;
@@ -2791,9 +2837,9 @@ printResults(TState *threads, StatsData *total, instr_time total_time,
 
 		for (i = 0; i < num_scripts; i++)
 		{
-			printf("SQL script %d: %s\n"
-			" - " INT64_FORMAT " transactions (%.1f%% of total, tps = %f)\n",
-				   i + 1, sql_script[i].name,
+			printf("SQL script %d, weight %d: %s\n"
+				" - "INT64_FORMAT" transactions (%.1f%% of total, tps = %f)\n",
+				   i + 1, sql_script[i].weight, sql_script[i].name,
 				   sql_script[i].stats.cnt,
 				   100.0 * sql_script[i].stats.cnt / total->cnt,
 				   sql_script[i].stats.cnt / time_include);
@@ -2887,6 +2933,7 @@ main(int argc, char **argv)
 	instr_time	conn_total_time;
 	int64		latency_late = 0;
 	StatsData	stats;
+	int			weight;
 	char	   *desc;
 
 	int			i;
@@ -3066,27 +3113,32 @@ main(int argc, char **argv)
 					exit(0);
 				}
 
+				weight = getWeight(optarg);
 				addScript(desc,
-						  process_builtin(findBuiltin(optarg, &desc), desc));
+						  process_builtin(findBuiltin(optarg, &desc), desc),
+						  weight);
 				benchmarking_option_set = true;
 				internal_script_used = true;
 				break;
 			case 'S':
 				addScript(desc,
 						  process_builtin(findBuiltin("select-only", &desc),
-										  desc));
+										  desc),
+						  1);
 				benchmarking_option_set = true;
 				internal_script_used = true;
 				break;
 			case 'N':
 				addScript(desc,
 						  process_builtin(findBuiltin("simple-update", &desc),
-										  desc));
+										  desc),
+						  1);
 				benchmarking_option_set = true;
 				internal_script_used = true;
 				break;
 			case 'f':
-				addScript(optarg, process_file(optarg));
+				weight = getWeight(optarg);
+				addScript(optarg, process_file(optarg), weight);
 				benchmarking_option_set = true;
 				break;
 			case 'D':
@@ -3225,11 +3277,16 @@ main(int argc, char **argv)
 	if (num_scripts == 0 && !is_init_mode)
 	{
 		addScript(desc,
-				  process_builtin(findBuiltin("tpcb-like", &desc), desc));
+				  process_builtin(findBuiltin("tpcb-like", &desc), desc),
+				  1);
 		benchmarking_option_set = true;
 		internal_script_used = true;
 	}
 
+	/* compute total_weight */
+	for (i = 0; i < num_scripts; i++)
+		total_weight += sql_script[i].weight;
+
 	/* show per script stats if several scripts are used */
 	if (num_scripts > 1)
 		per_script_stats = true;
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index ca3e158..52dc142 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -271,6 +271,9 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
         probability of drawing the test.
         Available builtin scripts are: <literal>tpcb-like</>,
         <literal>simple-update</> and <literal>select-only</>.
+        The provided <replaceable>scriptname</> needs only be an unambiguous
+        prefix of the builtin name, hence <literal>si</> would be enough to
+        select <literal>simple-update</>.
         With special name <literal>list</>, show the list of builtin scripts
         and exit immediately.
        </para>
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 5d24768..783cbf9 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -2675,22 +2675,32 @@ listAvailableScripts(void)
 	fprintf(stderr, "\n");
 }
 
+/* return commands for selected builtin script, if unambiguous */
 static char *
 findBuiltin(const char *name, char **desc)
 {
-	int			i;
+	int			i, found = 0, len = strlen(name);
+	char	   *commands = NULL;
 
 	for (i = 0; i < N_BUILTIN; i++)
 	{
-		if (strncmp(builtin_script[i].name, name,
-					strlen(builtin_script[i].name)) == 0)
+		if (strncmp(builtin_script[i].name, name, len) == 0)
 		{
 			*desc = builtin_script[i].desc;
-			return builtin_script[i].commands;
+			commands = builtin_script[i].commands;
+			found++;
 		}
 	}
 
-	fprintf(stderr, "no builtin script found for name \"%s\"\n", name);
+	if (found == 1)
+		return commands;
+
+	/* error cases */
+	if (found == 0)
+		fprintf(stderr, "no builtin script found for name \"%s\"\n", name);
+	else /* found > 1 */
+		fprintf(stderr,
+				"%d builtin scripts found for prefix \"%s\"\n", found, name);
 	listAvailableScripts();
 	exit(1);
 }
-- 
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