11/*
2- * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.40 2005/10/04 17:10:55 teodor Exp $
2+ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.41 2005/10/07 15:31:49 tgl Exp $
33 *
44 * pgbench: a simple benchmark program for PostgreSQL
55 * written by Tatsuo Ishii
4040#endif /* ! WIN32 */
4141
4242#include <ctype.h>
43- #include <search.h>
4443
4544extern char * optarg ;
4645extern int optind ;
@@ -90,6 +89,17 @@ char *login = NULL;
9089char * pwd = NULL ;
9190char * dbName ;
9291
92+ /* variable definitions */
93+ typedef struct
94+ {
95+ char * name ;/* variable name */
96+ char * value ;/* its value */
97+ }Variable ;
98+
99+ /*
100+ * structures used in custom query mode
101+ */
102+
93103typedef struct
94104{
95105PGconn * con ;/* connection handle to DB */
@@ -99,23 +109,12 @@ typedef struct
99109int ecnt ;/* error count */
100110int listen ;/* 0 indicates that an async query has
101111 * been sent */
102- void * variables ;
112+ Variable * variables ;/* array of variable definitions */
113+ int nvariables ;
103114struct timeval txn_begin ;/* used for measuring latencies */
104115int use_file ;/* index in sql_files for this client */
105116}CState ;
106117
107-
108- /*
109- * structures used in custom query mode
110- */
111-
112- /* variable definitions */
113- typedef struct
114- {
115- char * name ;/* variable name */
116- char * value ;/* its value */
117- }Variable ;
118-
119118/*
120119 * queries read from files
121120 */
@@ -180,7 +179,7 @@ usage(void)
180179static int
181180getrand (int min ,int max )
182181{
183- return ( min + (int ) (max * 1.0 * rand () / ( RAND_MAX + 1.0 ) + 0.5 ) );
182+ return min + (int ) ((( max - min ) * ( double ) random ()) / MAX_RANDOM_VALUE + 0.5 );
184183}
185184
186185/* set up a connection to the backend */
@@ -256,17 +255,26 @@ check(CState * state, PGresult *res, int n, int good)
256255static int
257256compareVariables (const void * v1 ,const void * v2 )
258257{
259- return strcmp (((Variable * )v1 )-> name , ((Variable * )v2 )-> name );
258+ return strcmp (((const Variable * )v1 )-> name ,
259+ ((const Variable * )v2 )-> name );
260260}
261261
262262static char *
263263getVariable (CState * st ,char * name )
264264{
265265Variable key = {name },* var ;
266266
267- var = tfind (& key ,& st -> variables ,compareVariables );
267+ /* On some versions of Solaris, bsearch of zero items dumps core */
268+ if (st -> nvariables <=0 )
269+ return NULL ;
270+
271+ var = (Variable * )bsearch ((void * )& key ,
272+ (void * )st -> variables ,
273+ st -> nvariables ,
274+ sizeof (Variable ),
275+ compareVariables );
268276if (var != NULL )
269- return ( * ( Variable * * ) var ) -> value ;
277+ return var -> value ;
270278else
271279return NULL ;
272280}
@@ -276,30 +284,55 @@ putVariable(CState * st, char *name, char *value)
276284{
277285Variable key = {name },* var ;
278286
279- var = tfind (& key ,& st -> variables ,compareVariables );
287+ /* On some versions of Solaris, bsearch of zero items dumps core */
288+ if (st -> nvariables > 0 )
289+ var = (Variable * )bsearch ((void * )& key ,
290+ (void * )st -> variables ,
291+ st -> nvariables ,
292+ sizeof (Variable ),
293+ compareVariables );
294+ else
295+ var = NULL ;
296+
280297if (var == NULL )
281298{
282- if ((var = malloc (sizeof (Variable )))== NULL )
299+ Variable * newvars ;
300+
301+ if (st -> variables )
302+ newvars = (Variable * )realloc (st -> variables ,
303+ (st -> nvariables + 1 )* sizeof (Variable ));
304+ else
305+ newvars = (Variable * )malloc (sizeof (Variable ));
306+
307+ if (newvars == NULL )
283308return false;
284309
310+ st -> variables = newvars ;
311+
312+ var = & newvars [st -> nvariables ];
313+
285314var -> name = NULL ;
286315var -> value = NULL ;
287316
288317if ((var -> name = strdup (name ))== NULL
289- || (var -> value = strdup (value ))== NULL
290- || tsearch (var ,& st -> variables ,compareVariables )== NULL )
318+ || (var -> value = strdup (value ))== NULL )
291319{
292320free (var -> name );
293321free (var -> value );
294- free (var );
295322return false;
296323}
324+
325+ st -> nvariables ++ ;
326+
327+ qsort ((void * )st -> variables ,st -> nvariables ,sizeof (Variable ),
328+ compareVariables );
297329}
298330else
299331{
300- free ((* (Variable * * )var )-> value );
301- if (((* (Variable * * )var )-> value = strdup (value ))== NULL )
332+ if ((value = strdup (value ))== NULL )
302333return false;
334+ free (var -> value );
335+ var -> value = value ;
303336}
304337
305338return true;
@@ -783,7 +816,7 @@ process_commands(char *buf)
783816return NULL ;
784817}
785818
786- if ((max = atoi (my_commands -> argv [3 ]))< min || max > RAND_MAX )
819+ if ((max = atoi (my_commands -> argv [3 ]))< min || max > MAX_RANDOM_VALUE )
787820{
788821fprintf (stderr ,"%s: invalid maximum number %s\n" ,
789822my_commands -> argv [0 ],my_commands -> argv [3 ]);