diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c index dab220d505..c005ef51a1 100644 --- a/contrib/pgbench/pgbench.c +++ b/contrib/pgbench/pgbench.c @@ -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 * written by Tatsuo Ishii @@ -40,7 +40,6 @@ #endif /* ! WIN32 */ #include -#include extern char *optarg; extern int optind; @@ -90,6 +89,17 @@ char *login = NULL; char *pwd = NULL; char *dbName; +/* variable definitions */ +typedef struct +{ + char *name; /* variable name */ + char *value; /* its value */ +} Variable; + +/* + * structures used in custom query mode + */ + typedef struct { PGconn *con; /* connection handle to DB */ @@ -99,23 +109,12 @@ typedef struct int ecnt; /* error count */ int listen; /* 0 indicates that an async query has * been sent */ - void *variables; + Variable *variables; /* array of variable definitions */ + int nvariables; struct timeval txn_begin; /* used for measuring latencies */ int use_file; /* index in sql_files for this client */ } CState; - -/* - * structures used in custom query mode - */ - -/* variable definitions */ -typedef struct -{ - char *name; /* variable name */ - char *value; /* its value */ -} Variable; - /* * queries read from files */ @@ -180,7 +179,7 @@ usage(void) static int 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 */ @@ -256,7 +255,8 @@ check(CState * state, PGresult *res, int n, int good) static int 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 * @@ -264,9 +264,17 @@ getVariable(CState * st, char *name) { 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) - return (*(Variable **)var)->value; + return var->value; else return NULL; } @@ -276,30 +284,55 @@ putVariable(CState * st, char *name, char *value) { 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 = 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; + st->variables = newvars; + + var = &newvars[st->nvariables]; + var->name = NULL; var->value = NULL; if ((var->name = strdup(name)) == NULL - || (var->value = strdup(value)) == NULL - || tsearch(var, &st->variables, compareVariables) == NULL) + || (var->value = strdup(value)) == NULL) { free(var->name); free(var->value); - free(var); return false; } + + st->nvariables++; + + qsort((void *) st->variables, st->nvariables, sizeof(Variable), + compareVariables); } else { - free((*(Variable **)var)->value); - if (((*(Variable **)var)->value = strdup(value)) == NULL) + if ((value = strdup(value)) == NULL) return false; + free(var->value); + var->value = value; } return true; @@ -783,7 +816,7 @@ process_commands(char *buf) 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", my_commands->argv[0], my_commands->argv[3]);