gni
authorTom Lane
Fri, 7 Oct 2005 15:31:49 +0000 (15:31 +0000)
committerTom Lane
Fri, 7 Oct 2005 15:31:49 +0000 (15:31 +0000)
contrib/pgbench/pgbench.c

index dab220d5053d6ce22f23e78eb9538b0ebface0b8..c005ef51a13cfe2029db250dbb93bd89ab8b57b4 100644 (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
  * 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]);