This commit is contained in:
Tom Lane 2005-10-07 15:31:49 +00:00
parent a84429a1aa
commit 6ae7671497
1 changed files with 60 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.40 2005/10/04 17:10:55 teodor Exp $ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.41 2005/10/07 15:31:49 tgl Exp $
* *
* pgbench: a simple benchmark program for PostgreSQL * pgbench: a simple benchmark program for PostgreSQL
* written by Tatsuo Ishii * written by Tatsuo Ishii
@ -40,7 +40,6 @@
#endif /* ! WIN32 */ #endif /* ! WIN32 */
#include <ctype.h> #include <ctype.h>
#include <search.h>
extern char *optarg; extern char *optarg;
extern int optind; extern int optind;
@ -90,6 +89,17 @@ char *login = NULL;
char *pwd = NULL; char *pwd = NULL;
char *dbName; char *dbName;
/* variable definitions */
typedef struct
{
char *name; /* variable name */
char *value; /* its value */
} Variable;
/*
* structures used in custom query mode
*/
typedef struct typedef struct
{ {
PGconn *con; /* connection handle to DB */ PGconn *con; /* connection handle to DB */
@ -99,23 +109,12 @@ typedef struct
int ecnt; /* error count */ int ecnt; /* error count */
int listen; /* 0 indicates that an async query has int listen; /* 0 indicates that an async query has
* been sent */ * been sent */
void *variables; Variable *variables; /* array of variable definitions */
int nvariables;
struct timeval txn_begin; /* used for measuring latencies */ struct timeval txn_begin; /* used for measuring latencies */
int use_file; /* index in sql_files for this client */ int use_file; /* index in sql_files for this client */
} CState; } CState;
/*
* structures used in custom query mode
*/
/* variable definitions */
typedef struct
{
char *name; /* variable name */
char *value; /* its value */
} Variable;
/* /*
* queries read from files * queries read from files
*/ */
@ -180,7 +179,7 @@ usage(void)
static int static int
getrand(int min, int max) getrand(int min, int max)
{ {
return (min + (int) (max * 1.0 * rand() / (RAND_MAX + 1.0) + 0.5)); return min + (int) (((max - min) * (double) random()) / MAX_RANDOM_VALUE + 0.5);
} }
/* set up a connection to the backend */ /* set up a connection to the backend */
@ -256,7 +255,8 @@ check(CState * state, PGresult *res, int n, int good)
static int static int
compareVariables(const void *v1, const void *v2) compareVariables(const void *v1, const void *v2)
{ {
return strcmp(((Variable *)v1)->name, ((Variable *)v2)->name); return strcmp(((const Variable *) v1)->name,
((const Variable *) v2)->name);
} }
static char * static char *
@ -264,9 +264,17 @@ getVariable(CState * st, char *name)
{ {
Variable key = { name }, *var; Variable key = { name }, *var;
var = tfind(&key, &st->variables, compareVariables); /* On some versions of Solaris, bsearch of zero items dumps core */
if (st->nvariables <= 0)
return NULL;
var = (Variable *) bsearch((void *) &key,
(void *) st->variables,
st->nvariables,
sizeof(Variable),
compareVariables);
if (var != NULL) if (var != NULL)
return (*(Variable **)var)->value; return var->value;
else else
return NULL; return NULL;
} }
@ -276,30 +284,55 @@ putVariable(CState * st, char *name, char *value)
{ {
Variable key = { name }, *var; Variable key = { name }, *var;
var = tfind(&key, &st->variables, compareVariables); /* On some versions of Solaris, bsearch of zero items dumps core */
if (st->nvariables > 0)
var = (Variable *) bsearch((void *) &key,
(void *) st->variables,
st->nvariables,
sizeof(Variable),
compareVariables);
else
var = NULL;
if (var == NULL) if (var == NULL)
{ {
if ((var = malloc(sizeof(Variable))) == NULL) Variable *newvars;
if (st->variables)
newvars = (Variable *) realloc(st->variables,
(st->nvariables + 1) * sizeof(Variable));
else
newvars = (Variable *) malloc(sizeof(Variable));
if (newvars == NULL)
return false; return false;
st->variables = newvars;
var = &newvars[st->nvariables];
var->name = NULL; var->name = NULL;
var->value = NULL; var->value = NULL;
if ((var->name = strdup(name)) == NULL if ((var->name = strdup(name)) == NULL
|| (var->value = strdup(value)) == NULL || (var->value = strdup(value)) == NULL)
|| tsearch(var, &st->variables, compareVariables) == NULL)
{ {
free(var->name); free(var->name);
free(var->value); free(var->value);
free(var);
return false; return false;
} }
st->nvariables++;
qsort((void *) st->variables, st->nvariables, sizeof(Variable),
compareVariables);
} }
else else
{ {
free((*(Variable **)var)->value); if ((value = strdup(value)) == NULL)
if (((*(Variable **)var)->value = strdup(value)) == NULL)
return false; return false;
free(var->value);
var->value = value;
} }
return true; return true;
@ -783,7 +816,7 @@ process_commands(char *buf)
return NULL; return NULL;
} }
if ((max = atoi(my_commands->argv[3])) < min || max > RAND_MAX) if ((max = atoi(my_commands->argv[3])) < min || max > MAX_RANDOM_VALUE)
{ {
fprintf(stderr, "%s: invalid maximum number %s\n", fprintf(stderr, "%s: invalid maximum number %s\n",
my_commands->argv[0], my_commands->argv[3]); my_commands->argv[0], my_commands->argv[3]);