~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleslap.cc

Merge Andrew - Enable boost filesystem requirement and fix linking requirements for it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
*/
73
73
 
74
74
#include "config.h"
 
75
 
75
76
#include "client_priv.h"
76
 
 
77
 
#include "option_string.h"
78
 
#include "stats.h"
79
 
#include "thread_context.h"
80
 
#include "conclusions.h"
81
 
#include "wakeup.h"
82
 
 
83
77
#include <signal.h>
84
78
#include <stdarg.h>
85
79
#include <sys/types.h>
94
88
#include <string>
95
89
#include <iostream>
96
90
#include <fstream>
 
91
#include <pthread.h>
97
92
#include <drizzled/configmake.h>
98
 
#include <memory>
99
 
 
100
93
/* Added this for string translation. */
101
94
#include <drizzled/gettext.h>
102
 
 
103
 
#include <boost/thread.hpp>
104
 
#include <boost/thread/mutex.hpp>
105
 
#include <boost/thread/condition_variable.hpp>
106
95
#include <boost/program_options.hpp>
107
 
#include <boost/scoped_ptr.hpp>
108
 
#include <drizzled/atomics.h>
109
96
 
110
 
#define SLAP_NAME "drizzleslap"
111
97
#define SLAP_VERSION "1.5"
112
98
 
113
99
#define HUGE_STRING_LENGTH 8196
122
108
static char *shared_memory_base_name=0;
123
109
#endif
124
110
 
125
 
client::Wakeup master_wakeup;
 
111
/* Global Thread counter */
 
112
uint32_t thread_counter;
 
113
pthread_mutex_t counter_mutex;
 
114
pthread_cond_t count_threshhold;
 
115
uint32_t master_wakeup;
 
116
pthread_mutex_t sleeper_mutex;
 
117
pthread_cond_t sleep_threshhold;
126
118
 
127
119
/* Global Thread timer */
128
120
static bool timer_alarm= false;
129
 
boost::mutex timer_alarm_mutex;
130
 
boost::condition_variable_any timer_alarm_threshold;
 
121
pthread_mutex_t timer_alarm_mutex;
 
122
pthread_cond_t timer_alarm_threshold;
131
123
 
132
124
std::vector < std::string > primary_keys;
133
125
 
134
 
drizzled::atomic<size_t> connection_count;
135
 
drizzled::atomic<uint64_t> failed_update_for_transaction;
136
 
 
137
126
static string host, 
138
127
  opt_password, 
139
128
  user,
172
161
  num_char_cols_opt,
173
162
  num_int_cols_opt;
174
163
string opt_label;
175
 
static uint32_t opt_set_random_seed;
 
164
static unsigned int opt_set_random_seed;
176
165
 
177
166
string auto_generate_selected_columns_opt;
178
167
 
179
168
/* Yes, we do set defaults here */
180
 
static uint32_t num_int_cols= 1;
181
 
static uint32_t num_char_cols= 1;
182
 
static uint32_t num_blob_cols= 0;
183
 
static uint32_t num_blob_cols_size;
184
 
static uint32_t num_blob_cols_size_min;
185
 
static uint32_t num_int_cols_index= 0;
186
 
static uint32_t num_char_cols_index= 0;
 
169
static unsigned int num_int_cols= 1;
 
170
static unsigned int num_char_cols= 1;
 
171
static unsigned int num_blob_cols= 0;
 
172
static unsigned int num_blob_cols_size;
 
173
static unsigned int num_blob_cols_size_min;
 
174
static unsigned int num_int_cols_index= 0;
 
175
static unsigned int num_char_cols_index= 0;
187
176
static uint32_t iterations;
188
177
static uint64_t actual_queries= 0;
189
178
static uint64_t auto_actual_queries;
196
185
string create_string;
197
186
std::vector <uint32_t> concurrency;
198
187
 
 
188
const char *default_dbug_option= "d:t:o,/tmp/drizzleslap.trace";
199
189
std::string opt_csv_str;
200
190
int csv_file;
201
191
 
202
192
static int process_options(void);
203
193
static uint32_t opt_drizzle_port= 0;
204
194
 
 
195
 
 
196
/* Types */
 
197
enum slap_query_t {
 
198
  SELECT_TYPE= 0,
 
199
  UPDATE_TYPE= 1,
 
200
  INSERT_TYPE= 2,
 
201
  UPDATE_TYPE_REQUIRES_PREFIX= 3,
 
202
  CREATE_TABLE_TYPE= 4,
 
203
  SELECT_TYPE_REQUIRES_PREFIX= 5,
 
204
  DELETE_TYPE_REQUIRES_PREFIX= 6
 
205
};
 
206
 
 
207
class Statement;
 
208
 
 
209
class Statement 
 
210
{
 
211
public:
 
212
  Statement(char *in_string,
 
213
            size_t in_length,
 
214
            slap_query_t in_type,
 
215
            Statement *in_next) :
 
216
    string(in_string),
 
217
    length(in_length),
 
218
    type(in_type),
 
219
    next(in_next)
 
220
  { }
 
221
 
 
222
  Statement() :
 
223
    string(NULL),
 
224
    length(0),
 
225
    type(),
 
226
    next(NULL)
 
227
  { }
 
228
 
 
229
  ~Statement()
 
230
  {
 
231
    if (string)
 
232
      free(string);
 
233
  }
 
234
   
 
235
  char *getString() const
 
236
  {
 
237
    return string;
 
238
  }
 
239
 
 
240
  size_t getLength() const
 
241
  {
 
242
    return length;
 
243
  }
 
244
 
 
245
  slap_query_t getType() const
 
246
  {
 
247
    return type;
 
248
  }
 
249
 
 
250
  Statement *getNext() const
 
251
  {
 
252
    return next;
 
253
  }
 
254
 
 
255
  void setString(char *in_string)
 
256
  {
 
257
    string= in_string;
 
258
  }
 
259
 
 
260
  void setString(size_t length_arg)
 
261
  {
 
262
    string= (char *)calloc(length_arg + 1, sizeof(char));
 
263
    length= length_arg;
 
264
  }
 
265
 
 
266
  void setString(size_t in_length, char in_char)
 
267
  {
 
268
    string[in_length]= in_char;
 
269
  }
 
270
 
 
271
  void setLength(size_t in_length)
 
272
  {
 
273
    length= in_length;
 
274
  }
 
275
 
 
276
  void setType(slap_query_t in_type)
 
277
  {
 
278
    type= in_type;
 
279
  }
 
280
 
 
281
  void setNext(Statement *in_next)
 
282
  {
 
283
    next= in_next;
 
284
  }
 
285
 
 
286
private:
 
287
  char *string;
 
288
  size_t length;
 
289
  slap_query_t type;
 
290
  Statement *next;
 
291
};
 
292
 
 
293
class OptionString;
 
294
 
 
295
class OptionString 
 
296
{
 
297
public:
 
298
  OptionString(char *in_string,
 
299
               size_t in_length,
 
300
               char *in_option,
 
301
               size_t in_option_length,
 
302
               OptionString *in_next) :
 
303
    string(in_string),
 
304
    length(in_length),
 
305
    option(in_option),
 
306
    option_length(in_option_length),
 
307
    next(in_next)
 
308
  { }  
 
309
 
 
310
  OptionString() :
 
311
    string(NULL),
 
312
    length(0),
 
313
    option(NULL),
 
314
    option_length(0),
 
315
    next(NULL)
 
316
  { }
 
317
 
 
318
  ~OptionString()
 
319
  {
 
320
    if (getString())
 
321
      free(getString());
 
322
    if (getOption())
 
323
      free(getOption());
 
324
  }
 
325
 
 
326
  char *getString() const
 
327
  {
 
328
    return string;
 
329
  }
 
330
 
 
331
  size_t getLength() const
 
332
  {
 
333
    return length;
 
334
  }
 
335
 
 
336
  char *getOption() const
 
337
  {
 
338
  return option;
 
339
  }
 
340
 
 
341
  size_t getOptionLength() const
 
342
  {
 
343
    return option_length;
 
344
  }
 
345
 
 
346
  OptionString *getNext() const
 
347
  {
 
348
    return next;
 
349
  }
 
350
 
 
351
  void setString(char *in_string)
 
352
  {
 
353
    string= in_string;
 
354
    length= strlen(in_string);
 
355
  }
 
356
 
 
357
  void setOption(char *in_option)
 
358
  {
 
359
    option= strdup(in_option);
 
360
    option_length= strlen(in_option);
 
361
  }
 
362
 
 
363
  void setNext(OptionString *in_next)
 
364
  {
 
365
    next= in_next;
 
366
  }
 
367
  
 
368
private:
 
369
  char *string;
 
370
  size_t length;
 
371
  char *option;
 
372
  size_t option_length;
 
373
  OptionString *next;
 
374
};
 
375
 
 
376
class Stats;
 
377
 
 
378
class Stats 
 
379
{
 
380
public:
 
381
  Stats(long int in_timing,
 
382
        uint32_t in_users,
 
383
        uint32_t in_real_users,
 
384
        uint32_t in_rows,
 
385
        long int in_create_timing,
 
386
        uint64_t in_create_count) :
 
387
    timing(in_timing),
 
388
    users(in_users),
 
389
    real_users(in_real_users),
 
390
    rows(in_rows),
 
391
    create_timing(in_create_timing),
 
392
    create_count(in_create_count)
 
393
  { }
 
394
 
 
395
  Stats() :
 
396
    timing(0),
 
397
    users(0),
 
398
    real_users(0),
 
399
    rows(0),
 
400
    create_timing(0),
 
401
    create_count(0)
 
402
  { }
 
403
 
 
404
  long int getTiming() const
 
405
  {
 
406
    return timing;
 
407
  }
 
408
 
 
409
  uint32_t getUsers() const
 
410
  {
 
411
    return users;
 
412
  }   
 
413
 
 
414
  uint32_t getRealUsers() const
 
415
  {
 
416
    return real_users;
 
417
  }
 
418
 
 
419
  uint64_t getRows() const
 
420
  {
 
421
    return rows;
 
422
  }
 
423
 
 
424
  long int getCreateTiming() const
 
425
  {
 
426
    return create_timing;
 
427
  }
 
428
 
 
429
  uint64_t getCreateCount() const
 
430
  {
 
431
    return create_count;
 
432
  }
 
433
 
 
434
  void setTiming(long int in_timing)
 
435
  {
 
436
  timing= in_timing;
 
437
  }
 
438
 
 
439
  void setUsers(uint32_t in_users)
 
440
  {
 
441
    users= in_users;
 
442
  }
 
443
 
 
444
  void setRealUsers(uint32_t in_real_users)
 
445
  {
 
446
    real_users= in_real_users;
 
447
  }
 
448
 
 
449
  void setRows(uint64_t in_rows)
 
450
  {
 
451
    rows= in_rows;
 
452
  }
 
453
   
 
454
  void setCreateTiming(long int in_create_timing)
 
455
  {
 
456
    create_timing= in_create_timing;
 
457
  }
 
458
 
 
459
  void setCreateCount(uint64_t in_create_count)
 
460
  {
 
461
  create_count= in_create_count;
 
462
  }
 
463
  
 
464
private:
 
465
  long int timing;
 
466
  uint32_t users;
 
467
  uint32_t real_users;
 
468
  uint64_t rows;
 
469
  long int create_timing;
 
470
  uint64_t create_count;
 
471
};
 
472
 
 
473
class ThreadContext;
 
474
 
 
475
class ThreadContext 
 
476
{
 
477
public:
 
478
  ThreadContext(Statement *in_stmt,
 
479
                uint64_t in_limit) :
 
480
    stmt(in_stmt),
 
481
    limit(in_limit)
 
482
  { }
 
483
 
 
484
  ThreadContext() :
 
485
    stmt(),
 
486
    limit(0)
 
487
  { }
 
488
 
 
489
  Statement *getStmt() const
 
490
  {
 
491
    return stmt;
 
492
  }
 
493
 
 
494
  uint64_t getLimit() const
 
495
  {
 
496
    return limit;
 
497
  }
 
498
 
 
499
  void setStmt(Statement *in_stmt)
 
500
  {
 
501
    stmt= in_stmt;
 
502
  }
 
503
 
 
504
  void setLimit(uint64_t in_limit)
 
505
  {
 
506
    limit= in_limit;
 
507
  }  
 
508
 
 
509
private:
 
510
  Statement *stmt;
 
511
  uint64_t limit;
 
512
};
 
513
 
 
514
class Conclusions;
 
515
 
 
516
class Conclusions 
 
517
{
 
518
 
 
519
public:
 
520
  Conclusions(char *in_engine,
 
521
              long int in_avg_timing,
 
522
              long int in_max_timing,
 
523
              long int in_min_timing,
 
524
              uint32_t in_users,
 
525
              uint32_t in_real_users,
 
526
              uint64_t in_avg_rows,
 
527
              long int in_sum_of_time,
 
528
              long int in_std_dev,
 
529
              long int in_create_avg_timing,
 
530
              long int in_create_max_timing,
 
531
              long int in_create_min_timing,
 
532
              uint64_t in_create_count,
 
533
              uint64_t in_max_rows,
 
534
              uint64_t in_min_rows) :
 
535
    engine(in_engine),
 
536
    avg_timing(in_avg_timing),
 
537
    max_timing(in_max_timing),
 
538
    min_timing(in_min_timing),
 
539
    users(in_users),
 
540
    real_users(in_real_users),
 
541
    avg_rows(in_avg_rows),
 
542
    sum_of_time(in_sum_of_time),
 
543
    std_dev(in_std_dev),
 
544
    create_avg_timing(in_create_avg_timing),
 
545
    create_max_timing(in_create_max_timing),
 
546
    create_min_timing(in_create_min_timing),
 
547
    create_count(in_create_count),
 
548
    max_rows(in_max_rows),
 
549
    min_rows(in_min_rows)
 
550
  { }
 
551
 
 
552
  Conclusions() :
 
553
    engine(NULL),
 
554
    avg_timing(0),
 
555
    max_timing(0),
 
556
    min_timing(0),
 
557
    users(0),
 
558
    real_users(0),
 
559
    avg_rows(0),
 
560
    sum_of_time(0),
 
561
    std_dev(0),
 
562
    create_avg_timing(0),
 
563
    create_max_timing(0),
 
564
    create_min_timing(0),
 
565
    create_count(0),
 
566
    max_rows(0),
 
567
    min_rows(0)
 
568
  { }
 
569
 
 
570
  char *getEngine() const
 
571
  {
 
572
    return engine;
 
573
  }
 
574
  
 
575
  long int getAvgTiming() const
 
576
  {
 
577
    return avg_timing;
 
578
  }
 
579
 
 
580
  long int getMaxTiming() const
 
581
  {
 
582
    return max_timing;
 
583
  }
 
584
 
 
585
  long int getMinTiming() const
 
586
  {
 
587
    return min_timing;
 
588
  }
 
589
 
 
590
  uint32_t getUsers() const
 
591
  {
 
592
    return users;
 
593
  }
 
594
 
 
595
  uint32_t getRealUsers() const
 
596
  {
 
597
    return real_users;
 
598
  }
 
599
 
 
600
  uint64_t getAvgRows() const
 
601
  {
 
602
    return avg_rows;
 
603
  }   
 
604
 
 
605
  long int getSumOfTime() const
 
606
  {
 
607
    return sum_of_time;
 
608
  }
 
609
 
 
610
  long int getStdDev() const
 
611
  {
 
612
    return std_dev;
 
613
  }
 
614
 
 
615
  long int getCreateAvgTiming() const
 
616
  {
 
617
    return create_avg_timing;
 
618
  }
 
619
 
 
620
  long int getCreateMaxTiming() const
 
621
  {
 
622
    return create_max_timing;
 
623
  }
 
624
 
 
625
  long int getCreateMinTiming() const
 
626
  {
 
627
    return create_min_timing;
 
628
  }
 
629
   
 
630
  uint64_t getCreateCount() const
 
631
  {
 
632
    return create_count;
 
633
  }
 
634
 
 
635
  uint64_t getMinRows() const
 
636
  {
 
637
    return min_rows;
 
638
  }
 
639
 
 
640
  uint64_t getMaxRows() const
 
641
  {
 
642
    return max_rows;
 
643
  }
 
644
 
 
645
  void setEngine(char *in_engine) 
 
646
  {
 
647
    engine= in_engine;
 
648
  }
 
649
  
 
650
  void setAvgTiming(long int in_avg_timing) 
 
651
  {
 
652
    avg_timing= in_avg_timing;
 
653
  }
 
654
 
 
655
  void setMaxTiming(long int in_max_timing) 
 
656
  {
 
657
    max_timing= in_max_timing;
 
658
  }
 
659
 
 
660
  void setMinTiming(long int in_min_timing) 
 
661
  {
 
662
    min_timing= in_min_timing;
 
663
  }
 
664
 
 
665
  void setUsers(uint32_t in_users) 
 
666
  {
 
667
    users= in_users;
 
668
  }
 
669
 
 
670
  void setRealUsers(uint32_t in_real_users) 
 
671
  {
 
672
    real_users= in_real_users;
 
673
  }
 
674
 
 
675
  void setAvgRows(uint64_t in_avg_rows) 
 
676
  {
 
677
    avg_rows= in_avg_rows;
 
678
  }   
 
679
 
 
680
  void setSumOfTime(long int in_sum_of_time) 
 
681
  {
 
682
    sum_of_time= in_sum_of_time;
 
683
  }
 
684
 
 
685
  void setStdDev(long int in_std_dev) 
 
686
  {
 
687
    std_dev= in_std_dev;
 
688
  }
 
689
 
 
690
  void setCreateAvgTiming(long int in_create_avg_timing) 
 
691
  {
 
692
    create_avg_timing= in_create_avg_timing;
 
693
  }
 
694
 
 
695
  void setCreateMaxTiming(long int in_create_max_timing) 
 
696
  {
 
697
    create_max_timing= in_create_max_timing;
 
698
  }
 
699
 
 
700
  void setCreateMinTiming(long int in_create_min_timing) 
 
701
  {
 
702
    create_min_timing= in_create_min_timing;
 
703
  }
 
704
   
 
705
  void setCreateCount(uint64_t in_create_count) 
 
706
  {
 
707
    create_count= in_create_count;
 
708
  }
 
709
 
 
710
  void setMinRows(uint64_t in_min_rows) 
 
711
  {
 
712
    min_rows= in_min_rows;
 
713
  }
 
714
 
 
715
  void setMaxRows(uint64_t in_max_rows) 
 
716
  {
 
717
    max_rows= in_max_rows;
 
718
  }
 
719
 
 
720
private:
 
721
  char *engine;
 
722
  long int avg_timing;
 
723
  long int max_timing;
 
724
  long int min_timing;
 
725
  uint32_t users;
 
726
  uint32_t real_users;
 
727
  uint64_t avg_rows;
 
728
  long int sum_of_time;
 
729
  long int std_dev;
 
730
  /* These are just for create time stats */
 
731
  long int create_avg_timing;
 
732
  long int create_max_timing;
 
733
  long int create_min_timing;
 
734
  uint64_t create_count;
 
735
  /* The following are not used yet */
 
736
  uint64_t max_rows;
 
737
  uint64_t min_rows;
 
738
};
 
739
 
 
740
 
205
741
static OptionString *engine_options= NULL;
206
742
static OptionString *query_options= NULL;
207
743
static Statement *pre_statements= NULL;
209
745
static Statement *create_statements= NULL;
210
746
 
211
747
static std::vector <Statement *> query_statements;
212
 
static uint32_t query_statements_count;
 
748
static unsigned int query_statements_count;
213
749
 
214
750
 
215
751
/* Prototypes */
216
 
void print_conclusions(Conclusions &con);
217
 
void print_conclusions_csv(Conclusions &con);
 
752
void print_conclusions(Conclusions *con);
 
753
void print_conclusions_csv(Conclusions *con);
218
754
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr);
219
755
uint32_t parse_comma(const char *string, std::vector <uint32_t> &range);
220
756
uint32_t parse_delimiter(const char *script, Statement **stmt, char delm);
221
757
uint32_t parse_option(const char *origin, OptionString **stmt, char delm);
222
 
static void drop_schema(drizzle_con_st &con, const char *db);
 
758
static int drop_schema(drizzle_con_st *con, const char *db);
223
759
uint32_t get_random_string(char *buf, size_t size);
224
760
static Statement *build_table_string(void);
225
761
static Statement *build_insert_string(void);
226
762
static Statement *build_update_string(void);
227
763
static Statement * build_select_string(bool key);
228
 
static int generate_primary_key_list(drizzle_con_st &con, OptionString *engine_stmt);
229
 
static void create_schema(drizzle_con_st &con, const char *db, Statement *stmt, OptionString *engine_stmt, Stats *sptr);
230
 
static void run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit);
 
764
static int generate_primary_key_list(drizzle_con_st *con, OptionString *engine_stmt);
 
765
static int create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
 
766
                         OptionString *engine_stmt, Stats *sptr);
 
767
static int run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur,
 
768
                         uint64_t limit);
 
769
extern "C" pthread_handler_t run_task(void *p);
 
770
extern "C" pthread_handler_t timer_thread(void *p);
231
771
void statement_cleanup(Statement *stmt);
232
772
void option_cleanup(OptionString *stmt);
233
 
void concurrency_loop(drizzle_con_st &con, uint32_t current, OptionString *eptr);
234
 
static void run_statements(drizzle_con_st &con, Statement *stmt);
235
 
void slap_connect(drizzle_con_st &con, bool connect_to_schema);
236
 
void slap_close(drizzle_con_st &con);
237
 
static int run_query(drizzle_con_st &con, drizzle_result_st *result, const char *query, int len);
238
 
void standard_deviation(Conclusions &con, Stats *sptr);
 
773
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr);
 
774
static int run_statements(drizzle_con_st *con, Statement *stmt);
 
775
void slap_connect(drizzle_con_st *con, bool connect_to_schema);
 
776
void slap_close(drizzle_con_st *con);
 
777
static int run_query(drizzle_con_st *con, drizzle_result_st *result, const char *query, int len);
 
778
void standard_deviation (Conclusions *con, Stats *sptr);
239
779
 
240
780
static const char ALPHANUMERICS[]=
241
781
"0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
265
805
    user_supplied_query.append(delimiter);
266
806
  }
267
807
}
268
 
 
269
 
 
270
 
static void run_task(ThreadContext *ctx)
271
 
{
272
 
  uint64_t counter= 0, queries;
273
 
  uint64_t detach_counter;
274
 
  uint32_t commit_counter;
275
 
  boost::scoped_ptr<drizzle_con_st> con_ap(new drizzle_con_st);
276
 
  drizzle_con_st &con= *con_ap.get();
277
 
  drizzle_result_st result;
278
 
  drizzle_row_t row;
279
 
  Statement *ptr;
280
 
 
281
 
  master_wakeup.wait();
282
 
 
283
 
  slap_connect(con, true);
284
 
 
285
 
  if (verbose >= 3)
286
 
    printf("connected!\n");
287
 
  queries= 0;
288
 
 
289
 
  commit_counter= 0;
290
 
  if (commit_rate)
291
 
    run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
292
 
 
293
 
limit_not_met:
294
 
  for (ptr= ctx->getStmt(), detach_counter= 0;
295
 
       ptr && ptr->getLength();
296
 
       ptr= ptr->getNext(), detach_counter++)
297
 
  {
298
 
    if (not opt_only_print && detach_rate && !(detach_counter % detach_rate))
299
 
    {
300
 
      slap_close(con);
301
 
      slap_connect(con, true);
302
 
    }
303
 
 
304
 
    /*
305
 
      We have to execute differently based on query type. This should become a function.
306
 
    */
307
 
    bool is_failed_update= false;
308
 
    if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
309
 
        (ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
310
 
    {
311
 
      int length;
312
 
      uint32_t key_val;
313
 
      char buffer[HUGE_STRING_LENGTH];
314
 
 
315
 
      /*
316
 
        This should only happen if some sort of new engine was
317
 
        implemented that didn't properly handle UPDATEs.
318
 
 
319
 
        Just in case someone runs this under an experimental engine we don't
320
 
        want a crash so the if() is placed here.
321
 
      */
322
 
      assert(primary_keys.size());
323
 
      if (primary_keys.size())
324
 
      {
325
 
        key_val= (uint32_t)(random() % primary_keys.size());
326
 
        const char *key;
327
 
        key= primary_keys[key_val].c_str();
328
 
 
329
 
        assert(key);
330
 
 
331
 
        length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
332
 
                         (int)ptr->getLength(), ptr->getString(), key);
333
 
 
334
 
        if (run_query(con, &result, buffer, length))
335
 
        {
336
 
          if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) and commit_rate)
337
 
          {
338
 
            // Expand to check to see if Innodb, if so we should restart the
339
 
            // transaction.  
340
 
 
341
 
            is_failed_update= true;
342
 
            failed_update_for_transaction.fetch_and_increment();
343
 
          }
344
 
          else
345
 
          {
346
 
            fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
347
 
                    SLAP_NAME, (uint32_t)length, buffer, drizzle_con_error(&con));
348
 
            abort();
349
 
          }
350
 
        }
351
 
      }
352
 
    }
353
 
    else
354
 
    {
355
 
      if (run_query(con, &result, ptr->getString(), ptr->getLength()))
356
 
      {
357
 
        if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) and commit_rate)
358
 
        {
359
 
          // Expand to check to see if Innodb, if so we should restart the
360
 
          // transaction.
361
 
 
362
 
          is_failed_update= true;
363
 
          failed_update_for_transaction.fetch_and_increment();
364
 
        }
365
 
        else
366
 
        {
367
 
          fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
368
 
                  SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
369
 
          abort();
370
 
        }
371
 
      }
372
 
    }
373
 
 
374
 
    if (not opt_only_print and not is_failed_update)
375
 
    {
376
 
      while ((row = drizzle_row_next(&result)))
377
 
        counter++;
378
 
      drizzle_result_free(&result);
379
 
    }
380
 
    queries++;
381
 
 
382
 
    if (commit_rate && (++commit_counter == commit_rate) and not is_failed_update)
383
 
    {
384
 
      commit_counter= 0;
385
 
      run_query(con, NULL, "COMMIT", strlen("COMMIT"));
386
 
    }
387
 
 
388
 
    /* If the timer is set, and the alarm is not active then end */
389
 
    if (opt_timer_length && timer_alarm == false)
390
 
      goto end;
391
 
 
392
 
    /* If limit has been reached, and we are not in a timer_alarm just end */
393
 
    if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm == false)
394
 
      goto end;
395
 
  }
396
 
 
397
 
  if (opt_timer_length && timer_alarm == true)
398
 
    goto limit_not_met;
399
 
 
400
 
  if (ctx->getLimit() && queries < ctx->getLimit())
401
 
    goto limit_not_met;
402
 
 
403
 
 
404
 
end:
405
 
  if (commit_rate)
406
 
    run_query(con, NULL, "COMMIT", strlen("COMMIT"));
407
 
 
408
 
  slap_close(con);
409
 
 
410
 
  delete ctx;
411
 
}
412
 
 
413
808
/**
414
809
 * commandline_options is the set of all options that can only be called via the command line.
415
810
 
436
831
    po::options_description commandline_options("Options used only in command line");
437
832
    commandline_options.add_options()
438
833
      ("help,?","Display this help and exit")
439
 
      ("info","Gives information and exit")
 
834
      ("info,i","Gives information and exit")
440
835
      ("burnin",po::value<bool>(&opt_burnin)->default_value(false)->zero_tokens(),
441
836
       "Run full test case in infinite loop")
442
837
      ("ignore-sql-errors", po::value<bool>(&opt_ignore_sql_errors)->default_value(false)->zero_tokens(),
518
913
       "Delay the startup of threads by a random number of microsends (the maximum of the delay")
519
914
      ("delimiter,F",po::value<string>(&delimiter)->default_value("\n"),
520
915
       "Delimiter to use in SQL statements supplied in file or command line")
521
 
      ("engine,e",po::value<string>(&default_engine)->default_value(""),
522
 
       "Storage engine to use for creating the table")
 
916
      ("engine ,e",po::value<string>(&default_engine)->default_value(""),
 
917
       "Storage engien to use for creating the table")
523
918
      ("set-random-seed",
524
919
       po::value<uint32_t>(&opt_set_random_seed)->default_value(0), 
525
920
       "Seed for random number generator (srandom(3)) ") 
552
947
 
553
948
    std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
554
949
 
555
 
    if (user_config_dir.compare(0, 2, "~/") == 0)
556
 
    {
557
 
      char *homedir;
558
 
      homedir= getenv("HOME");
559
 
      if (homedir != NULL)
560
 
        user_config_dir.replace(0, 1, homedir);
561
 
    }
562
 
 
563
950
    uint64_t temp_drizzle_port= 0;
564
 
    boost::scoped_ptr<drizzle_con_st> con_ap(new drizzle_con_st);
565
 
    drizzle_con_st &con= *con_ap.get();
 
951
    drizzle_con_st con;
566
952
    OptionString *eptr;
567
953
 
568
 
    // Disable allow_guessing
569
 
    int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
570
954
 
571
955
    po::variables_map vm;
572
956
    po::store(po::command_line_parser(argc, argv).options(long_options).
573
 
              style(style).extra_parser(parse_password_arg).run(), vm);
 
957
            extra_parser(parse_password_arg).run(), vm);
574
958
 
575
959
    std::string user_config_dir_slap(user_config_dir);
576
960
    user_config_dir_slap.append("/drizzle/drizzleslap.cnf"); 
593
977
    po::notify(vm);
594
978
 
595
979
    if (process_options())
596
 
      abort();
 
980
      exit(1);
597
981
 
598
982
    if ( vm.count("help") || vm.count("info"))
599
983
    {
600
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
 
984
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
601
985
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
602
986
      puts("Copyright (C) 2008 Sun Microsystems");
603
987
      puts("This software comes with ABSOLUTELY NO WARRANTY. "
606
990
           "license\n");
607
991
      puts("Run a query multiple times against the server\n");
608
992
      cout << long_options << endl;
609
 
      abort();
 
993
      exit(0);
610
994
    }   
611
995
 
612
996
    if (vm.count("protocol"))
621
1005
      else
622
1006
      {
623
1007
        cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
624
 
        abort();
 
1008
        exit(-1);
625
1009
      }
626
1010
    }
627
1011
    if (vm.count("port")) 
631
1015
      if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
632
1016
      {
633
1017
        fprintf(stderr, _("Value supplied for port is not valid.\n"));
634
 
        abort();
 
1018
        exit(1);
635
1019
      }
636
1020
      else
637
1021
      {
641
1025
 
642
1026
  if ( vm.count("password") )
643
1027
  {
644
 
    if (not opt_password.empty())
 
1028
    if (!opt_password.empty())
645
1029
      opt_password.erase();
646
1030
    if (password == PASSWORD_SENTINEL)
647
1031
    {
662
1046
 
663
1047
    if ( vm.count("version") )
664
1048
    {
665
 
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",SLAP_NAME, SLAP_VERSION,
 
1049
      printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname, SLAP_VERSION,
666
1050
          drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
667
 
      abort();
 
1051
      exit(0);
668
1052
    }
669
1053
 
670
1054
    /* Seed the random number generator if we will be using it. */
671
1055
    if (auto_generate_sql)
672
1056
    {
673
1057
      if (opt_set_random_seed == 0)
674
 
        opt_set_random_seed= (uint32_t)time(NULL);
 
1058
        opt_set_random_seed= (unsigned int)time(NULL);
675
1059
      srandom(opt_set_random_seed);
676
1060
    }
677
1061
 
678
1062
    /* globals? Yes, so we only have to run strlen once */
679
1063
    delimiter_length= delimiter.length();
680
1064
 
681
 
    slap_connect(con, false);
 
1065
    slap_connect(&con, false);
 
1066
 
 
1067
    pthread_mutex_init(&counter_mutex, NULL);
 
1068
    pthread_cond_init(&count_threshhold, NULL);
 
1069
    pthread_mutex_init(&sleeper_mutex, NULL);
 
1070
    pthread_cond_init(&sleep_threshhold, NULL);
 
1071
    pthread_mutex_init(&timer_alarm_mutex, NULL);
 
1072
    pthread_cond_init(&timer_alarm_threshold, NULL);
 
1073
 
682
1074
 
683
1075
    /* Main iterations loop */
684
1076
burnin:
694
1086
      if (concurrency.size())
695
1087
      {
696
1088
        for (current= &concurrency[0]; current && *current; current++)
697
 
          concurrency_loop(con, *current, eptr);
 
1089
          concurrency_loop(&con, *current, eptr);
698
1090
      }
699
1091
      else
700
1092
      {
701
1093
        uint32_t infinite= 1;
702
1094
        do {
703
 
          concurrency_loop(con, infinite, eptr);
 
1095
          concurrency_loop(&con, infinite, eptr);
704
1096
        }
705
1097
        while (infinite++);
706
1098
      }
707
1099
 
708
 
      if (not opt_preserve)
709
 
        drop_schema(con, create_schema_string.c_str());
 
1100
      if (!opt_preserve)
 
1101
        drop_schema(&con, create_schema_string.c_str());
710
1102
 
711
1103
    } while (eptr ? (eptr= eptr->getNext()) : 0);
712
1104
 
713
1105
    if (opt_burnin)
714
1106
      goto burnin;
715
1107
 
716
 
    slap_close(con);
 
1108
    pthread_mutex_destroy(&counter_mutex);
 
1109
    pthread_cond_destroy(&count_threshhold);
 
1110
    pthread_mutex_destroy(&sleeper_mutex);
 
1111
    pthread_cond_destroy(&sleep_threshhold);
 
1112
    pthread_mutex_destroy(&timer_alarm_mutex);
 
1113
    pthread_cond_destroy(&timer_alarm_threshold);
 
1114
 
 
1115
    slap_close(&con);
717
1116
 
718
1117
    /* now free all the strings we created */
719
 
    if (not opt_password.empty())
 
1118
    if (!opt_password.empty())
720
1119
      opt_password.erase();
721
1120
 
722
1121
    concurrency.clear();
748
1147
  return 0;
749
1148
}
750
1149
 
751
 
void concurrency_loop(drizzle_con_st &con, uint32_t current, OptionString *eptr)
 
1150
void concurrency_loop(drizzle_con_st *con, uint32_t current, OptionString *eptr)
752
1151
{
753
1152
  Stats *head_sptr;
754
1153
  Stats *sptr;
759
1158
  if (head_sptr == NULL)
760
1159
  {
761
1160
    fprintf(stderr,"Error allocating memory in concurrency_loop\n");
762
 
    abort();
 
1161
    exit(1);
763
1162
  }
764
1163
 
765
1164
  if (auto_actual_queries)
793
1192
    if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
794
1193
      generate_primary_key_list(con, eptr);
795
1194
 
796
 
    if (not pre_system.empty())
 
1195
    if (commit_rate)
 
1196
      run_query(con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
1197
 
 
1198
    if (!pre_system.empty())
797
1199
    {
798
1200
      int ret= system(pre_system.c_str());
799
1201
      assert(ret != -1);
800
1202
    }
 
1203
       
801
1204
 
802
1205
    /*
803
1206
      Pre statements are always run after all other logic so they can
811
1214
    if (post_statements)
812
1215
      run_statements(con, post_statements);
813
1216
 
814
 
    if (not post_system.empty())
 
1217
    if (!post_system.empty())
815
1218
    {
816
1219
      int ret=  system(post_system.c_str());
817
1220
      assert(ret !=-1);
827
1230
 
828
1231
  generate_stats(&conclusion, eptr, head_sptr);
829
1232
 
830
 
  if (not opt_silent)
831
 
    print_conclusions(conclusion);
832
 
  if (not opt_csv_str.empty())
833
 
    print_conclusions_csv(conclusion);
 
1233
  if (!opt_silent)
 
1234
    print_conclusions(&conclusion);
 
1235
  if (!opt_csv_str.empty())
 
1236
    print_conclusions_csv(&conclusion);
834
1237
 
835
1238
  delete [] head_sptr;
836
1239
}
837
1240
 
838
1241
 
839
 
uint32_t get_random_string(char *buf, size_t size)
 
1242
uint
 
1243
get_random_string(char *buf, size_t size)
840
1244
{
841
1245
  char *buf_ptr= buf;
842
1246
 
856
1260
build_table_string(void)
857
1261
{
858
1262
  char       buf[HUGE_STRING_LENGTH];
859
 
  uint32_t        col_count;
 
1263
  unsigned int        col_count;
860
1264
  Statement *ptr;
861
1265
  string table_string;
862
1266
 
882
1286
 
883
1287
  if (auto_generate_sql_secondary_indexes)
884
1288
  {
885
 
    for (uint32_t count= 0; count < auto_generate_sql_secondary_indexes; count++)
 
1289
    unsigned int count;
 
1290
 
 
1291
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
886
1292
    {
887
1293
      if (count) /* Except for the first pass we add a comma */
888
1294
        table_string.append(",");
891
1297
          > HUGE_STRING_LENGTH)
892
1298
      {
893
1299
        fprintf(stderr, "Memory Allocation error in create table\n");
894
 
        abort();
 
1300
        exit(1);
895
1301
      }
896
1302
      table_string.append(buf);
897
1303
    }
909
1315
                     col_count, col_count) > HUGE_STRING_LENGTH)
910
1316
        {
911
1317
          fprintf(stderr, "Memory Allocation error in create table\n");
912
 
          abort();
 
1318
          exit(1);
913
1319
        }
914
1320
      }
915
1321
      else
918
1324
            > HUGE_STRING_LENGTH)
919
1325
        {
920
1326
          fprintf(stderr, "Memory Allocation error in create table\n");
921
 
          abort();
 
1327
          exit(1);
922
1328
        }
923
1329
      }
924
1330
      table_string.append(buf);
937
1343
                     col_count, col_count) > HUGE_STRING_LENGTH)
938
1344
        {
939
1345
          fprintf(stderr, "Memory Allocation error in creating table\n");
940
 
          abort();
 
1346
          exit(1);
941
1347
        }
942
1348
      }
943
1349
      else
946
1352
                     col_count) > HUGE_STRING_LENGTH)
947
1353
        {
948
1354
          fprintf(stderr, "Memory Allocation error in creating table\n");
949
 
          abort();
 
1355
          exit(1);
950
1356
        }
951
1357
      }
952
1358
      table_string.append(buf);
962
1368
                   col_count) > HUGE_STRING_LENGTH)
963
1369
      {
964
1370
        fprintf(stderr, "Memory Allocation error in creating table\n");
965
 
        abort();
 
1371
        exit(1);
966
1372
      }
967
1373
      table_string.append(buf);
968
1374
 
976
1382
  if (ptr->getString()==NULL)
977
1383
  {
978
1384
    fprintf(stderr, "Memory Allocation error in creating table\n");
979
 
    abort();
 
1385
    exit(1);
980
1386
  }
981
1387
  ptr->setType(CREATE_TABLE_TYPE);
982
1388
  strcpy(ptr->getString(), table_string.c_str());
993
1399
build_update_string(void)
994
1400
{
995
1401
  char       buf[HUGE_STRING_LENGTH];
996
 
  uint32_t        col_count;
 
1402
  unsigned int        col_count;
997
1403
  Statement *ptr;
998
1404
  string update_string;
999
1405
 
1008
1414
                   random()) > HUGE_STRING_LENGTH)
1009
1415
      {
1010
1416
        fprintf(stderr, "Memory Allocation error in creating update\n");
1011
 
        abort();
 
1417
        exit(1);
1012
1418
      }
1013
1419
      update_string.append(buf);
1014
1420
 
1027
1433
          > HUGE_STRING_LENGTH)
1028
1434
      {
1029
1435
        fprintf(stderr, "Memory Allocation error in creating update\n");
1030
 
        abort();
 
1436
        exit(1);
1031
1437
      }
1032
1438
      update_string.append(buf);
1033
1439
 
1045
1451
  if (ptr->getString() == NULL)
1046
1452
  {
1047
1453
    fprintf(stderr, "Memory Allocation error in creating update\n");
1048
 
    abort();
 
1454
    exit(1);
1049
1455
  }
1050
1456
  if (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary)
1051
1457
    ptr->setType(UPDATE_TYPE_REQUIRES_PREFIX);
1066
1472
build_insert_string(void)
1067
1473
{
1068
1474
  char       buf[HUGE_STRING_LENGTH];
1069
 
  uint32_t        col_count;
 
1475
  unsigned int        col_count;
1070
1476
  Statement *ptr;
1071
1477
  string insert_string;
1072
1478
 
1092
1498
 
1093
1499
  if (auto_generate_sql_secondary_indexes)
1094
1500
  {
1095
 
    uint32_t count;
 
1501
    unsigned int count;
1096
1502
 
1097
1503
    for (count= 0; count < auto_generate_sql_secondary_indexes; count++)
1098
1504
    {
1112
1518
      if (snprintf(buf, HUGE_STRING_LENGTH, "%ld", random()) > HUGE_STRING_LENGTH)
1113
1519
      {
1114
1520
        fprintf(stderr, "Memory Allocation error in creating insert\n");
1115
 
        abort();
 
1521
        exit(1);
1116
1522
      }
1117
1523
      insert_string.append(buf);
1118
1524
 
1140
1546
 
1141
1547
    for (col_count= 1; col_count <= num_blob_cols; col_count++)
1142
1548
    {
1143
 
      uint32_t buf_len;
1144
 
      uint32_t size;
1145
 
      uint32_t difference= num_blob_cols_size - num_blob_cols_size_min;
 
1549
      unsigned int buf_len;
 
1550
      unsigned int size;
 
1551
      unsigned int difference= num_blob_cols_size - num_blob_cols_size_min;
1146
1552
 
1147
1553
      size= difference ? (num_blob_cols_size_min + (random() % difference)) :
1148
1554
        num_blob_cols_size;
1165
1571
  if (ptr->getString()==NULL)
1166
1572
  {
1167
1573
    fprintf(stderr, "Memory Allocation error in creating select\n");
1168
 
    abort();
 
1574
    exit(1);
1169
1575
  }
1170
1576
  ptr->setType(INSERT_TYPE);
1171
1577
  strcpy(ptr->getString(), insert_string.c_str());
1183
1589
build_select_string(bool key)
1184
1590
{
1185
1591
  char       buf[HUGE_STRING_LENGTH];
1186
 
  uint32_t        col_count;
 
1592
  unsigned int        col_count;
1187
1593
  Statement *ptr;
1188
1594
  string query_string;
1189
1595
 
1190
1596
  query_string.reserve(HUGE_STRING_LENGTH);
1191
1597
 
1192
1598
  query_string.append("SELECT ", 7);
1193
 
  if (not auto_generate_selected_columns_opt.empty())
 
1599
  if (!auto_generate_selected_columns_opt.empty())
1194
1600
  {
1195
1601
    query_string.append(auto_generate_selected_columns_opt.c_str());
1196
1602
  }
1202
1608
          > HUGE_STRING_LENGTH)
1203
1609
      {
1204
1610
        fprintf(stderr, "Memory Allocation error in creating select\n");
1205
 
        abort();
 
1611
        exit(1);
1206
1612
      }
1207
1613
      query_string.append(buf);
1208
1614
 
1216
1622
          > HUGE_STRING_LENGTH)
1217
1623
      {
1218
1624
        fprintf(stderr, "Memory Allocation error in creating select\n");
1219
 
        abort();
 
1625
        exit(1);
1220
1626
      }
1221
1627
      query_string.append(buf);
1222
1628
 
1230
1636
          > HUGE_STRING_LENGTH)
1231
1637
      {
1232
1638
        fprintf(stderr, "Memory Allocation error in creating select\n");
1233
 
        abort();
 
1639
        exit(1);
1234
1640
      }
1235
1641
      query_string.append(buf);
1236
1642
 
1249
1655
  if (ptr->getString() == NULL)
1250
1656
  {
1251
1657
    fprintf(stderr, "Memory Allocation error in creating select\n");
1252
 
    abort();
 
1658
    exit(1);
1253
1659
  }
1254
1660
  if ((key) &&
1255
1661
      (auto_generate_sql_autoincrement || auto_generate_sql_guid_primary))
1265
1671
{
1266
1672
  struct stat sbuf;
1267
1673
  OptionString *sql_type;
1268
 
  uint32_t sql_type_count= 0;
 
1674
  unsigned int sql_type_count= 0;
1269
1675
  ssize_t bytes_read= 0;
1270
1676
  
1271
1677
  if (user.empty())
1274
1680
  verbose= opt_verbose.length();
1275
1681
 
1276
1682
  /* If something is created we clean it up, otherwise we leave schemas alone */
1277
 
  if ( (not create_string.empty()) || auto_generate_sql)
 
1683
  if ( (!create_string.empty()) || auto_generate_sql)
1278
1684
    opt_preserve= false;
1279
1685
 
1280
 
  if (auto_generate_sql && (not create_string.empty() || !user_supplied_query.empty()))
 
1686
  if (auto_generate_sql && (!create_string.empty() || !user_supplied_query.empty()))
1281
1687
  {
1282
1688
    fprintf(stderr,
1283
1689
            "%s: Can't use --auto-generate-sql when create and query strings are specified!\n",
1284
 
            SLAP_NAME);
1285
 
    abort();
 
1690
            internal::my_progname);
 
1691
    exit(1);
1286
1692
  }
1287
1693
 
1288
1694
  if (auto_generate_sql && auto_generate_sql_guid_primary &&
1290
1696
  {
1291
1697
    fprintf(stderr,
1292
1698
            "%s: Either auto-generate-sql-guid-primary or auto-generate-sql-add-autoincrement can be used!\n",
1293
 
            SLAP_NAME);
1294
 
    abort();
 
1699
            internal::my_progname);
 
1700
    exit(1);
1295
1701
  }
1296
1702
 
1297
1703
  if (auto_generate_sql && num_of_query && auto_actual_queries)
1298
1704
  {
1299
1705
    fprintf(stderr,
1300
1706
            "%s: Either auto-generate-sql-execute-number or number-of-queries can be used!\n",
1301
 
            SLAP_NAME);
1302
 
    abort();
 
1707
            internal::my_progname);
 
1708
    exit(1);
1303
1709
  }
1304
1710
 
1305
 
  parse_comma(not concurrency_str.empty() ? concurrency_str.c_str() : "1", concurrency);
 
1711
  parse_comma(!concurrency_str.empty() ? concurrency_str.c_str() : "1", concurrency);
1306
1712
 
1307
 
  if (not opt_csv_str.empty())
 
1713
  if (!opt_csv_str.empty())
1308
1714
  {
1309
1715
    opt_silent= true;
1310
1716
 
1318
1724
                          S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
1319
1725
      {
1320
1726
        fprintf(stderr,"%s: Could not open csv file: %sn\n",
1321
 
                SLAP_NAME, opt_csv_str.c_str());
1322
 
        abort();
 
1727
                internal::my_progname, opt_csv_str.c_str());
 
1728
        exit(1);
1323
1729
      }
1324
1730
    }
1325
1731
  }
1327
1733
  if (opt_only_print)
1328
1734
    opt_silent= true;
1329
1735
 
1330
 
  if (not num_int_cols_opt.empty())
 
1736
  if (!num_int_cols_opt.empty())
1331
1737
  {
1332
1738
    OptionString *str;
1333
1739
    parse_option(num_int_cols_opt.c_str(), &str, ',');
1337
1743
    option_cleanup(str);
1338
1744
  }
1339
1745
 
1340
 
  if (not num_char_cols_opt.empty())
 
1746
  if (!num_char_cols_opt.empty())
1341
1747
  {
1342
1748
    OptionString *str;
1343
1749
    parse_option(num_char_cols_opt.c_str(), &str, ',');
1349
1755
    option_cleanup(str);
1350
1756
  }
1351
1757
 
1352
 
  if (not num_blob_cols_opt.empty())
 
1758
  if (!num_blob_cols_opt.empty())
1353
1759
  {
1354
1760
    OptionString *str;
1355
1761
    parse_option(num_blob_cols_opt.c_str(), &str, ',');
1433
1839
        {
1434
1840
          fprintf(stderr,
1435
1841
                  "%s: Can't perform key test without a primary key!\n",
1436
 
                  SLAP_NAME);
1437
 
          abort();
 
1842
                  internal::my_progname);
 
1843
          exit(1);
1438
1844
        }
1439
1845
 
1440
1846
        query_statements[sql_type_count]= build_select_string(true);
1469
1875
        {
1470
1876
          fprintf(stderr,
1471
1877
                  "%s: Can't perform update test without a primary key!\n",
1472
 
                  SLAP_NAME);
1473
 
          abort();
 
1878
                  internal::my_progname);
 
1879
          exit(1);
1474
1880
        }
1475
1881
 
1476
1882
        query_statements[sql_type_count]= build_update_string();
1511
1917
  }
1512
1918
  else
1513
1919
  {
1514
 
    if (not create_string.empty() && !stat(create_string.c_str(), &sbuf))
 
1920
    if (!create_string.empty() && !stat(create_string.c_str(), &sbuf))
1515
1921
    {
1516
1922
      int data_file;
1517
1923
      std::vector<char> tmp_string;
1518
 
      if (not S_ISREG(sbuf.st_mode))
 
1924
      if (!S_ISREG(sbuf.st_mode))
1519
1925
      {
1520
1926
        fprintf(stderr,"%s: Create file was not a regular file\n",
1521
 
                SLAP_NAME);
1522
 
        abort();
 
1927
                internal::my_progname);
 
1928
        exit(1);
1523
1929
      }
1524
1930
      if ((data_file= open(create_string.c_str(), O_RDWR)) == -1)
1525
1931
      {
1526
 
        fprintf(stderr,"%s: Could not open create file\n", SLAP_NAME);
1527
 
        abort();
 
1932
        fprintf(stderr,"%s: Could not open create file\n", internal::my_progname);
 
1933
        exit(1);
1528
1934
      }
1529
1935
      if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1530
1936
      {
1531
1937
        fprintf(stderr, "Request for more memory than architecture supports\n");
1532
 
        abort();
 
1938
        exit(1);
1533
1939
      }
1534
1940
      tmp_string.resize(sbuf.st_size + 1);
1535
1941
      bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
1541
1947
      }
1542
1948
      parse_delimiter(&tmp_string[0], &create_statements, delimiter[0]);
1543
1949
    }
1544
 
    else if (not create_string.empty())
 
1950
    else if (!create_string.empty())
1545
1951
    {
1546
1952
      parse_delimiter(create_string.c_str(), &create_statements, delimiter[0]);
1547
1953
    }
1548
1954
 
1549
1955
    /* Set this up till we fully support options on user generated queries */
1550
 
    if (not user_supplied_query.empty())
 
1956
    if (!user_supplied_query.empty())
1551
1957
    {
1552
1958
      query_statements_count=
1553
1959
        parse_option("default", &query_options, ',');
1555
1961
      query_statements.resize(query_statements_count);
1556
1962
    }
1557
1963
 
1558
 
    if (not user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
 
1964
    if (!user_supplied_query.empty() && !stat(user_supplied_query.c_str(), &sbuf))
1559
1965
    {
1560
1966
      int data_file;
1561
1967
      std::vector<char> tmp_string;
1562
1968
 
1563
 
      if (not S_ISREG(sbuf.st_mode))
 
1969
      if (!S_ISREG(sbuf.st_mode))
1564
1970
      {
1565
1971
        fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1566
 
                SLAP_NAME);
1567
 
        abort();
 
1972
                internal::my_progname);
 
1973
        exit(1);
1568
1974
      }
1569
1975
      if ((data_file= open(user_supplied_query.c_str(), O_RDWR)) == -1)
1570
1976
      {
1571
 
        fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1572
 
        abort();
 
1977
        fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
1978
        exit(1);
1573
1979
      }
1574
1980
      if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1575
1981
      {
1576
1982
        fprintf(stderr, "Request for more memory than architecture supports\n");
1577
 
        abort();
 
1983
        exit(1);
1578
1984
      }
1579
1985
      tmp_string.resize((size_t)(sbuf.st_size + 1));
1580
1986
      bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
1584
1990
      {
1585
1991
        fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1586
1992
      }
1587
 
      if (not user_supplied_query.empty())
 
1993
      if (!user_supplied_query.empty())
1588
1994
        actual_queries= parse_delimiter(&tmp_string[0], &query_statements[0],
1589
1995
                                        delimiter[0]);
1590
1996
    }
1591
 
    else if (not user_supplied_query.empty())
 
1997
    else if (!user_supplied_query.empty())
1592
1998
    {
1593
1999
      actual_queries= parse_delimiter(user_supplied_query.c_str(), &query_statements[0],
1594
2000
                                      delimiter[0]);
1595
2001
    }
1596
2002
  }
1597
2003
 
1598
 
  if (not user_supplied_pre_statements.empty()
 
2004
  if (!user_supplied_pre_statements.empty()
1599
2005
      && !stat(user_supplied_pre_statements.c_str(), &sbuf))
1600
2006
  {
1601
2007
    int data_file;
1602
2008
    std::vector<char> tmp_string;
1603
2009
 
1604
 
    if (not S_ISREG(sbuf.st_mode))
 
2010
    if (!S_ISREG(sbuf.st_mode))
1605
2011
    {
1606
2012
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1607
 
              SLAP_NAME);
1608
 
      abort();
 
2013
              internal::my_progname);
 
2014
      exit(1);
1609
2015
    }
1610
2016
    if ((data_file= open(user_supplied_pre_statements.c_str(), O_RDWR)) == -1)
1611
2017
    {
1612
 
      fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1613
 
      abort();
 
2018
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2019
      exit(1);
1614
2020
    }
1615
2021
    if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1616
2022
    {
1617
2023
      fprintf(stderr, "Request for more memory than architecture supports\n");
1618
 
      abort();
 
2024
      exit(1);
1619
2025
    }
1620
2026
    tmp_string.resize((size_t)(sbuf.st_size + 1));
1621
2027
    bytes_read= read(data_file, (unsigned char*) &tmp_string[0],
1625
2031
    {
1626
2032
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1627
2033
    }
1628
 
    if (not user_supplied_pre_statements.empty())
 
2034
    if (!user_supplied_pre_statements.empty())
1629
2035
      (void)parse_delimiter(&tmp_string[0], &pre_statements,
1630
2036
                            delimiter[0]);
1631
2037
  }
1632
 
  else if (not user_supplied_pre_statements.empty())
 
2038
  else if (!user_supplied_pre_statements.empty())
1633
2039
  {
1634
2040
    (void)parse_delimiter(user_supplied_pre_statements.c_str(),
1635
2041
                          &pre_statements,
1636
2042
                          delimiter[0]);
1637
2043
  }
1638
2044
 
1639
 
  if (not user_supplied_post_statements.empty()
 
2045
  if (!user_supplied_post_statements.empty()
1640
2046
      && !stat(user_supplied_post_statements.c_str(), &sbuf))
1641
2047
  {
1642
2048
    int data_file;
1643
2049
    std::vector<char> tmp_string;
1644
2050
 
1645
 
    if (not S_ISREG(sbuf.st_mode))
 
2051
    if (!S_ISREG(sbuf.st_mode))
1646
2052
    {
1647
2053
      fprintf(stderr,"%s: User query supplied file was not a regular file\n",
1648
 
              SLAP_NAME);
1649
 
      abort();
 
2054
              internal::my_progname);
 
2055
      exit(1);
1650
2056
    }
1651
2057
    if ((data_file= open(user_supplied_post_statements.c_str(), O_RDWR)) == -1)
1652
2058
    {
1653
 
      fprintf(stderr,"%s: Could not open query supplied file\n", SLAP_NAME);
1654
 
      abort();
 
2059
      fprintf(stderr,"%s: Could not open query supplied file\n", internal::my_progname);
 
2060
      exit(1);
1655
2061
    }
1656
2062
 
1657
2063
    if ((uint64_t)(sbuf.st_size + 1) > SIZE_MAX)
1658
2064
    {
1659
2065
      fprintf(stderr, "Request for more memory than architecture supports\n");
1660
 
      abort();
 
2066
      exit(1);
1661
2067
    }
1662
2068
    tmp_string.resize((size_t)(sbuf.st_size + 1));
1663
2069
 
1668
2074
    {
1669
2075
      fprintf(stderr, "Problem reading file: read less bytes than requested\n");
1670
2076
    }
1671
 
    if (not user_supplied_post_statements.empty())
 
2077
    if (!user_supplied_post_statements.empty())
1672
2078
      (void)parse_delimiter(&tmp_string[0], &post_statements,
1673
2079
                            delimiter[0]);
1674
2080
  }
1675
 
  else if (not user_supplied_post_statements.empty())
 
2081
  else if (!user_supplied_post_statements.empty())
1676
2082
  {
1677
2083
    (void)parse_delimiter(user_supplied_post_statements.c_str(), &post_statements,
1678
2084
                          delimiter[0]);
1681
2087
  if (verbose >= 2)
1682
2088
    printf("Parsing engines to use.\n");
1683
2089
 
1684
 
  if (not default_engine.empty())
 
2090
  if (!default_engine.empty())
1685
2091
    parse_option(default_engine.c_str(), &engine_options, ',');
1686
2092
 
1687
2093
  if (tty_password)
1690
2096
}
1691
2097
 
1692
2098
 
1693
 
static int run_query(drizzle_con_st &con, drizzle_result_st *result,
 
2099
static int run_query(drizzle_con_st *con, drizzle_result_st *result,
1694
2100
                     const char *query, int len)
1695
2101
{
1696
2102
  drizzle_return_t ret;
1698
2104
 
1699
2105
  if (opt_only_print)
1700
2106
  {
1701
 
    printf("/* CON: %" PRIu64 " */ %.*s;\n",
1702
 
           (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1703
 
           len, query);
 
2107
    printf("%.*s;\n", len, query);
1704
2108
    return 0;
1705
2109
  }
1706
2110
 
1710
2114
  if (result == NULL)
1711
2115
    result= &result_buffer;
1712
2116
 
1713
 
  result= drizzle_query(&con, result, query, len, &ret);
 
2117
  result= drizzle_query(con, result, query, len, &ret);
1714
2118
 
1715
2119
  if (ret == DRIZZLE_RETURN_OK)
1716
2120
    ret= drizzle_result_buffer(result);
1723
2127
 
1724
2128
 
1725
2129
static int
1726
 
generate_primary_key_list(drizzle_con_st &con, OptionString *engine_stmt)
 
2130
generate_primary_key_list(drizzle_con_st *con, OptionString *engine_stmt)
1727
2131
{
1728
2132
  drizzle_result_st result;
1729
2133
  drizzle_row_t row;
1744
2148
  {
1745
2149
    if (run_query(con, &result, "SELECT id from t1", strlen("SELECT id from t1")))
1746
2150
    {
1747
 
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", SLAP_NAME,
1748
 
              drizzle_con_error(&con));
1749
 
      abort();
 
2151
      fprintf(stderr,"%s: Cannot select GUID primary keys. (%s)\n", internal::my_progname,
 
2152
              drizzle_con_error(con));
 
2153
      exit(1);
1750
2154
    }
1751
2155
 
1752
2156
    uint64_t num_rows_ret= drizzle_result_row_count(&result);
1753
2157
    if (num_rows_ret > SIZE_MAX)
1754
2158
    {
1755
2159
      fprintf(stderr, "More primary keys than than architecture supports\n");
1756
 
      abort();
 
2160
      exit(1);
1757
2161
    }
1758
2162
    size_t primary_keys_number_of;
1759
2163
    primary_keys_number_of= (size_t)num_rows_ret;
1778
2182
  return(0);
1779
2183
}
1780
2184
 
1781
 
static void create_schema(drizzle_con_st &con, const char *db, Statement *stmt, OptionString *engine_stmt, Stats *sptr)
 
2185
static int
 
2186
create_schema(drizzle_con_st *con, const char *db, Statement *stmt,
 
2187
              OptionString *engine_stmt, Stats *sptr)
1782
2188
{
1783
2189
  char query[HUGE_STRING_LENGTH];
1784
2190
  Statement *ptr;
1785
2191
  Statement *after_create;
1786
2192
  int len;
 
2193
  uint64_t count;
1787
2194
  struct timeval start_time, end_time;
1788
2195
 
1789
2196
 
1796
2203
 
1797
2204
  if (run_query(con, NULL, query, len))
1798
2205
  {
1799
 
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", SLAP_NAME, db,
1800
 
            drizzle_con_error(&con));
1801
 
    abort();
 
2206
    fprintf(stderr,"%s: Cannot create schema %s : %s\n", internal::my_progname, db,
 
2207
            drizzle_con_error(con));
 
2208
    exit(1);
1802
2209
  }
1803
2210
  else
1804
2211
  {
1807
2214
 
1808
2215
  if (opt_only_print)
1809
2216
  {
1810
 
    printf("/* CON: %" PRIu64 " */ use %s;\n",
1811
 
           (uint64_t)drizzle_context(drizzle_con_drizzle(&con)),
1812
 
           db);
 
2217
    printf("use %s;\n", db);
1813
2218
  }
1814
2219
  else
1815
2220
  {
1819
2224
    if (verbose >= 3)
1820
2225
      printf("%s;\n", query);
1821
2226
 
1822
 
    if (drizzle_select_db(&con,  &result, db, &ret) == NULL ||
 
2227
    if (drizzle_select_db(con,  &result, db, &ret) == NULL ||
1823
2228
        ret != DRIZZLE_RETURN_OK)
1824
2229
    {
1825
 
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",SLAP_NAME, db,
 
2230
      fprintf(stderr,"%s: Cannot select schema '%s': %s\n",internal::my_progname, db,
1826
2231
              ret == DRIZZLE_RETURN_ERROR_CODE ?
1827
 
              drizzle_result_error(&result) : drizzle_con_error(&con));
1828
 
      abort();
 
2232
              drizzle_result_error(&result) : drizzle_con_error(con));
 
2233
      exit(1);
1829
2234
    }
1830
2235
    drizzle_result_free(&result);
1831
2236
    sptr->setCreateCount(sptr->getCreateCount()+1);
1837
2242
                  engine_stmt->getString());
1838
2243
    if (run_query(con, NULL, query, len))
1839
2244
    {
1840
 
      fprintf(stderr,"%s: Cannot set default engine: %s\n", SLAP_NAME,
1841
 
              drizzle_con_error(&con));
1842
 
      abort();
 
2245
      fprintf(stderr,"%s: Cannot set default engine: %s\n", internal::my_progname,
 
2246
              drizzle_con_error(con));
 
2247
      exit(1);
1843
2248
    }
1844
2249
    sptr->setCreateCount(sptr->getCreateCount()+1);
1845
2250
  }
1846
2251
 
1847
 
  uint64_t count= 0;
 
2252
  count= 0;
1848
2253
  after_create= stmt;
1849
2254
 
1850
2255
limit_not_met:
1862
2267
      if (run_query(con, NULL, buffer, strlen(buffer)))
1863
2268
      {
1864
2269
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1865
 
                SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1866
 
        if (not opt_ignore_sql_errors)
1867
 
          abort();
 
2270
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2271
        if (!opt_ignore_sql_errors)
 
2272
          exit(1);
1868
2273
      }
1869
2274
      sptr->setCreateCount(sptr->getCreateCount()+1);
1870
2275
    }
1873
2278
      if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1874
2279
      {
1875
2280
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1876
 
                SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1877
 
        if (not opt_ignore_sql_errors)
1878
 
          abort();
 
2281
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2282
        if (!opt_ignore_sql_errors)
 
2283
          exit(1);
1879
2284
      }
1880
2285
      sptr->setCreateCount(sptr->getCreateCount()+1);
1881
2286
    }
1891
2296
  gettimeofday(&end_time, NULL);
1892
2297
 
1893
2298
  sptr->setCreateTiming(timedif(end_time, start_time));
 
2299
 
 
2300
  return(0);
1894
2301
}
1895
2302
 
1896
 
static void drop_schema(drizzle_con_st &con, const char *db)
 
2303
static int
 
2304
drop_schema(drizzle_con_st *con, const char *db)
1897
2305
{
1898
2306
  char query[HUGE_STRING_LENGTH];
1899
2307
  int len;
1903
2311
  if (run_query(con, NULL, query, len))
1904
2312
  {
1905
2313
    fprintf(stderr,"%s: Cannot drop database '%s' ERROR : %s\n",
1906
 
            SLAP_NAME, db, drizzle_con_error(&con));
1907
 
    abort();
 
2314
            internal::my_progname, db, drizzle_con_error(con));
 
2315
    exit(1);
1908
2316
  }
 
2317
 
 
2318
 
 
2319
 
 
2320
  return(0);
1909
2321
}
1910
2322
 
1911
 
static void run_statements(drizzle_con_st &con, Statement *stmt)
 
2323
static int
 
2324
run_statements(drizzle_con_st *con, Statement *stmt)
1912
2325
{
1913
 
  for (Statement *ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
 
2326
  Statement *ptr;
 
2327
 
 
2328
  for (ptr= stmt; ptr && ptr->getLength(); ptr= ptr->getNext())
1914
2329
  {
1915
2330
    if (run_query(con, NULL, ptr->getString(), ptr->getLength()))
1916
2331
    {
1917
2332
      fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
1918
 
              SLAP_NAME, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
1919
 
      abort();
 
2333
              internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(con));
 
2334
      exit(1);
1920
2335
    }
1921
2336
  }
 
2337
 
 
2338
  return(0);
1922
2339
}
1923
2340
 
1924
 
 
1925
 
static void timer_thread()
 
2341
static int
 
2342
run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
1926
2343
{
 
2344
  uint32_t y;
 
2345
  unsigned int real_concurrency;
 
2346
  struct timeval start_time, end_time;
 
2347
  OptionString *sql_type;
 
2348
  pthread_t mainthread;            /* Thread descriptor */
 
2349
  pthread_attr_t attr;          /* Thread attributes */
 
2350
 
 
2351
 
 
2352
  pthread_attr_init(&attr);
 
2353
  pthread_attr_setdetachstate(&attr,
 
2354
                              PTHREAD_CREATE_DETACHED);
 
2355
 
 
2356
  pthread_mutex_lock(&counter_mutex);
 
2357
  thread_counter= 0;
 
2358
 
 
2359
  pthread_mutex_lock(&sleeper_mutex);
 
2360
  master_wakeup= 1;
 
2361
  pthread_mutex_unlock(&sleeper_mutex);
 
2362
 
 
2363
  real_concurrency= 0;
 
2364
 
 
2365
  for (y= 0, sql_type= query_options;
 
2366
       y < query_statements_count;
 
2367
       y++, sql_type= sql_type->getNext())
 
2368
  {
 
2369
    unsigned int options_loop= 1;
 
2370
 
 
2371
    if (sql_type->getOption())
 
2372
    {
 
2373
      options_loop= strtol(sql_type->getOption(),
 
2374
                           (char **)NULL, 10);
 
2375
      options_loop= options_loop ? options_loop : 1;
 
2376
    }
 
2377
 
 
2378
    while (options_loop--)
 
2379
    {
 
2380
      for (uint32_t x= 0; x < concur; x++)
 
2381
      {
 
2382
        ThreadContext *con;
 
2383
        con= new ThreadContext;
 
2384
        if (con == NULL)
 
2385
        {
 
2386
          fprintf(stderr, "Memory Allocation error in scheduler\n");
 
2387
          exit(1);
 
2388
        }
 
2389
        con->setStmt(stmts[y]);
 
2390
        con->setLimit(limit);
 
2391
 
 
2392
        real_concurrency++;
 
2393
        /* now you create the thread */
 
2394
        if (pthread_create(&mainthread, &attr, run_task,
 
2395
                           (void *)con) != 0)
 
2396
        {
 
2397
          fprintf(stderr,"%s: Could not create thread\n", internal::my_progname);
 
2398
          exit(1);
 
2399
        }
 
2400
        thread_counter++;
 
2401
      }
 
2402
    }
 
2403
  }
 
2404
 
1927
2405
  /*
1928
 
    We lock around the initial call in case were we in a loop. This
1929
 
    also keeps the value properly syncronized across call threads.
 
2406
    The timer_thread belongs to all threads so it too obeys the wakeup
 
2407
    call that run tasks obey.
1930
2408
  */
1931
 
  master_wakeup.wait();
1932
 
 
1933
 
  {
1934
 
    boost::mutex::scoped_lock scopedLock(timer_alarm_mutex);
1935
 
 
1936
 
    boost::xtime xt; 
1937
 
    xtime_get(&xt, boost::TIME_UTC); 
1938
 
    xt.sec += opt_timer_length; 
1939
 
 
1940
 
    (void)timer_alarm_threshold.timed_wait(scopedLock, xt);
1941
 
  }
1942
 
 
1943
 
  {
1944
 
    boost::mutex::scoped_lock scopedLock(timer_alarm_mutex);
1945
 
    timer_alarm= false;
1946
 
  }
1947
 
}
1948
 
 
1949
 
typedef boost::shared_ptr<boost::thread> Thread;
1950
 
typedef std::vector <Thread> Threads;
1951
 
static void run_scheduler(Stats *sptr, Statement **stmts, uint32_t concur, uint64_t limit)
1952
 
{
1953
 
  uint32_t real_concurrency;
1954
 
  struct timeval start_time, end_time;
1955
 
 
1956
 
  Threads threads;
1957
 
 
1958
 
  {
1959
 
    OptionString *sql_type;
1960
 
 
1961
 
    master_wakeup.reset();
1962
 
 
1963
 
    real_concurrency= 0;
1964
 
 
1965
 
    uint32_t y;
1966
 
    for (y= 0, sql_type= query_options;
1967
 
         y < query_statements_count;
1968
 
         y++, sql_type= sql_type->getNext())
1969
 
    {
1970
 
      uint32_t options_loop= 1;
1971
 
 
1972
 
      if (sql_type->getOption())
1973
 
      {
1974
 
        options_loop= strtol(sql_type->getOption(),
1975
 
                             (char **)NULL, 10);
1976
 
        options_loop= options_loop ? options_loop : 1;
1977
 
      }
1978
 
 
1979
 
      while (options_loop--)
1980
 
      {
1981
 
        for (uint32_t x= 0; x < concur; x++)
1982
 
        {
1983
 
          ThreadContext *con;
1984
 
          con= new ThreadContext;
1985
 
          if (con == NULL)
1986
 
          {
1987
 
            fprintf(stderr, "Memory Allocation error in scheduler\n");
1988
 
            abort();
1989
 
          }
1990
 
          con->setStmt(stmts[y]);
1991
 
          con->setLimit(limit);
1992
 
 
1993
 
          real_concurrency++;
1994
 
 
1995
 
          /* now you create the thread */
1996
 
          Thread thread;
1997
 
          thread= Thread(new boost::thread(boost::bind(&run_task, con)));
1998
 
          threads.push_back(thread);
1999
 
 
2000
 
        }
2001
 
      }
2002
 
    }
2003
 
 
2004
 
    /*
2005
 
      The timer_thread belongs to all threads so it too obeys the wakeup
2006
 
      call that run tasks obey.
2007
 
    */
2008
 
    if (opt_timer_length)
2009
 
    {
2010
 
      {
2011
 
        boost::mutex::scoped_lock alarmLock(timer_alarm_mutex);
2012
 
        timer_alarm= true;
2013
 
      }
2014
 
 
2015
 
      Thread thread;
2016
 
      thread= Thread(new boost::thread(&timer_thread));
2017
 
      threads.push_back(thread);
2018
 
    }
2019
 
  }
2020
 
 
2021
 
  master_wakeup.start();
 
2409
  if (opt_timer_length)
 
2410
  {
 
2411
    pthread_mutex_lock(&timer_alarm_mutex);
 
2412
    timer_alarm= true;
 
2413
    pthread_mutex_unlock(&timer_alarm_mutex);
 
2414
 
 
2415
    if (pthread_create(&mainthread, &attr, timer_thread,
 
2416
                       (void *)&opt_timer_length) != 0)
 
2417
    {
 
2418
      fprintf(stderr,"%s: Could not create timer thread\n", internal::my_progname);
 
2419
      exit(1);
 
2420
    }
 
2421
  }
 
2422
 
 
2423
  pthread_mutex_unlock(&counter_mutex);
 
2424
  pthread_attr_destroy(&attr);
 
2425
 
 
2426
  pthread_mutex_lock(&sleeper_mutex);
 
2427
  master_wakeup= 0;
 
2428
  pthread_mutex_unlock(&sleeper_mutex);
 
2429
  pthread_cond_broadcast(&sleep_threshhold);
2022
2430
 
2023
2431
  gettimeofday(&start_time, NULL);
2024
2432
 
2025
2433
  /*
2026
2434
    We loop until we know that all children have cleaned up.
2027
2435
  */
2028
 
  for (Threads::iterator iter= threads.begin(); iter != threads.end(); iter++)
 
2436
  pthread_mutex_lock(&counter_mutex);
 
2437
  while (thread_counter)
2029
2438
  {
2030
 
    (*iter)->join();
 
2439
    struct timespec abstime;
 
2440
 
 
2441
    set_timespec(abstime, 3);
 
2442
    pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
2031
2443
  }
 
2444
  pthread_mutex_unlock(&counter_mutex);
2032
2445
 
2033
2446
  gettimeofday(&end_time, NULL);
2034
2447
 
 
2448
 
2035
2449
  sptr->setTiming(timedif(end_time, start_time));
2036
2450
  sptr->setUsers(concur);
2037
2451
  sptr->setRealUsers(real_concurrency);
2038
2452
  sptr->setRows(limit);
 
2453
 
 
2454
  return(0);
 
2455
}
 
2456
 
 
2457
 
 
2458
pthread_handler_t timer_thread(void *p)
 
2459
{
 
2460
  uint32_t *timer_length= (uint32_t *)p;
 
2461
  struct timespec abstime;
 
2462
 
 
2463
 
 
2464
  /*
 
2465
    We lock around the initial call in case were we in a loop. This
 
2466
    also keeps the value properly syncronized across call threads.
 
2467
  */
 
2468
  pthread_mutex_lock(&sleeper_mutex);
 
2469
  while (master_wakeup)
 
2470
  {
 
2471
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
 
2472
  }
 
2473
  pthread_mutex_unlock(&sleeper_mutex);
 
2474
 
 
2475
  set_timespec(abstime, *timer_length);
 
2476
 
 
2477
  pthread_mutex_lock(&timer_alarm_mutex);
 
2478
  pthread_cond_timedwait(&timer_alarm_threshold, &timer_alarm_mutex, &abstime);
 
2479
  pthread_mutex_unlock(&timer_alarm_mutex);
 
2480
 
 
2481
  pthread_mutex_lock(&timer_alarm_mutex);
 
2482
  timer_alarm= false;
 
2483
  pthread_mutex_unlock(&timer_alarm_mutex);
 
2484
 
 
2485
  return(0);
 
2486
}
 
2487
 
 
2488
pthread_handler_t run_task(void *p)
 
2489
{
 
2490
  uint64_t counter= 0, queries;
 
2491
  uint64_t detach_counter;
 
2492
  unsigned int commit_counter;
 
2493
  drizzle_con_st con;
 
2494
  drizzle_result_st result;
 
2495
  drizzle_row_t row;
 
2496
  Statement *ptr;
 
2497
  ThreadContext *ctx= (ThreadContext *)p;
 
2498
 
 
2499
  pthread_mutex_lock(&sleeper_mutex);
 
2500
  while (master_wakeup)
 
2501
  {
 
2502
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
 
2503
  }
 
2504
  pthread_mutex_unlock(&sleeper_mutex);
 
2505
 
 
2506
  slap_connect(&con, true);
 
2507
 
 
2508
  if (verbose >= 3)
 
2509
    printf("connected!\n");
 
2510
  queries= 0;
 
2511
 
 
2512
  commit_counter= 0;
 
2513
  if (commit_rate)
 
2514
    run_query(&con, NULL, "SET AUTOCOMMIT=0", strlen("SET AUTOCOMMIT=0"));
 
2515
 
 
2516
limit_not_met:
 
2517
  for (ptr= ctx->getStmt(), detach_counter= 0;
 
2518
       ptr && ptr->getLength();
 
2519
       ptr= ptr->getNext(), detach_counter++)
 
2520
  {
 
2521
    if (!opt_only_print && detach_rate && !(detach_counter % detach_rate))
 
2522
    {
 
2523
      slap_close(&con);
 
2524
      slap_connect(&con, true);
 
2525
    }
 
2526
 
 
2527
    /*
 
2528
      We have to execute differently based on query type. This should become a function.
 
2529
    */
 
2530
    if ((ptr->getType() == UPDATE_TYPE_REQUIRES_PREFIX) ||
 
2531
        (ptr->getType() == SELECT_TYPE_REQUIRES_PREFIX))
 
2532
    {
 
2533
      int length;
 
2534
      unsigned int key_val;
 
2535
      char buffer[HUGE_STRING_LENGTH];
 
2536
 
 
2537
      /*
 
2538
        This should only happen if some sort of new engine was
 
2539
        implemented that didn't properly handle UPDATEs.
 
2540
 
 
2541
        Just in case someone runs this under an experimental engine we don't
 
2542
        want a crash so the if() is placed here.
 
2543
      */
 
2544
      assert(primary_keys.size());
 
2545
      if (primary_keys.size())
 
2546
      {
 
2547
        key_val= (unsigned int)(random() % primary_keys.size());
 
2548
        const char *key;
 
2549
        key= primary_keys[key_val].c_str();
 
2550
 
 
2551
        assert(key);
 
2552
 
 
2553
        length= snprintf(buffer, HUGE_STRING_LENGTH, "%.*s '%s'",
 
2554
                         (int)ptr->getLength(), ptr->getString(), key);
 
2555
 
 
2556
        if (run_query(&con, &result, buffer, length))
 
2557
        {
 
2558
          fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
 
2559
                  internal::my_progname, (uint32_t)length, buffer, drizzle_con_error(&con));
 
2560
          exit(1);
 
2561
        }
 
2562
      }
 
2563
    }
 
2564
    else
 
2565
    {
 
2566
      if (run_query(&con, &result, ptr->getString(), ptr->getLength()))
 
2567
      {
 
2568
        fprintf(stderr,"%s: Cannot run query %.*s ERROR : %s\n",
 
2569
                internal::my_progname, (uint32_t)ptr->getLength(), ptr->getString(), drizzle_con_error(&con));
 
2570
        exit(1);
 
2571
      }
 
2572
    }
 
2573
 
 
2574
    if (!opt_only_print)
 
2575
    {
 
2576
      while ((row = drizzle_row_next(&result)))
 
2577
        counter++;
 
2578
      drizzle_result_free(&result);
 
2579
    }
 
2580
    queries++;
 
2581
 
 
2582
    if (commit_rate && (++commit_counter == commit_rate))
 
2583
    {
 
2584
      commit_counter= 0;
 
2585
      run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
 
2586
    }
 
2587
 
 
2588
    /* If the timer is set, and the alarm is not active then end */
 
2589
    if (opt_timer_length && timer_alarm == false)
 
2590
      goto end;
 
2591
 
 
2592
    /* If limit has been reached, and we are not in a timer_alarm just end */
 
2593
    if (ctx->getLimit() && queries == ctx->getLimit() && timer_alarm == false)
 
2594
      goto end;
 
2595
  }
 
2596
 
 
2597
  if (opt_timer_length && timer_alarm == true)
 
2598
    goto limit_not_met;
 
2599
 
 
2600
  if (ctx->getLimit() && queries < ctx->getLimit())
 
2601
    goto limit_not_met;
 
2602
 
 
2603
 
 
2604
end:
 
2605
  if (commit_rate)
 
2606
    run_query(&con, NULL, "COMMIT", strlen("COMMIT"));
 
2607
 
 
2608
  slap_close(&con);
 
2609
 
 
2610
  pthread_mutex_lock(&counter_mutex);
 
2611
  thread_counter--;
 
2612
  pthread_cond_signal(&count_threshhold);
 
2613
  pthread_mutex_unlock(&counter_mutex);
 
2614
 
 
2615
  delete ctx;
 
2616
 
 
2617
  return(0);
2039
2618
}
2040
2619
 
2041
2620
/*
2042
2621
  Parse records from comma seperated string. : is a reserved character and is used for options
2043
2622
  on variables.
2044
2623
*/
2045
 
uint32_t parse_option(const char *origin, OptionString **stmt, char delm)
 
2624
uint
 
2625
parse_option(const char *origin, OptionString **stmt, char delm)
2046
2626
{
2047
2627
  char *string;
2048
2628
  char *begin_ptr;
2092
2672
    if (tmp->getString() == NULL)
2093
2673
    {
2094
2674
      fprintf(stderr,"Error allocating memory while parsing options\n");
2095
 
      abort();
 
2675
      exit(1);
2096
2676
    }
2097
2677
 
2098
2678
    if (isspace(*begin_ptr))
2115
2695
  Raw parsing interface. If you want the slap specific parser look at
2116
2696
  parse_option.
2117
2697
*/
2118
 
uint32_t parse_delimiter(const char *script, Statement **stmt, char delm)
 
2698
uint
 
2699
parse_delimiter(const char *script, Statement **stmt, char delm)
2119
2700
{
2120
2701
  char *retstr;
2121
2702
  char *ptr= (char *)script;
2132
2713
    if (tmp == NULL)
2133
2714
    {
2134
2715
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2135
 
      abort();
 
2716
      exit(1);
2136
2717
    }
2137
2718
 
2138
2719
    count++;
2141
2722
    if (tmp->getString() == NULL)
2142
2723
    {
2143
2724
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2144
 
      abort();
 
2725
      exit(1);
2145
2726
    }
2146
2727
 
2147
2728
    memcpy(tmp->getString(), ptr, tmp->getLength());
2156
2737
    if (tmp->getString() == NULL)
2157
2738
    {
2158
2739
      fprintf(stderr,"Error allocating memory while parsing delimiter\n");
2159
 
      abort();
 
2740
      exit(1);
2160
2741
    }
2161
2742
    memcpy(tmp->getString(), ptr, tmp->getLength());
2162
2743
    count++;
2171
2752
  number ranges from a comma seperated string.
2172
2753
  In restrospect, this is a lousy name from this function.
2173
2754
*/
2174
 
uint32_t parse_comma(const char *string, std::vector <uint32_t> &range)
 
2755
uint
 
2756
parse_comma(const char *string, std::vector <uint32_t> &range)
2175
2757
{
2176
 
  uint32_t count= 1; /* We know that there is always one */
 
2758
  unsigned int count= 1,x; /* We know that there is always one */
2177
2759
  char *retstr;
2178
2760
  char *ptr= (char *)string;
2179
 
  uint32_t *nptr;
 
2761
  unsigned int *nptr;
2180
2762
 
2181
2763
  for (;*ptr; ptr++)
2182
2764
    if (*ptr == ',') count++;
2186
2768
  nptr= &range[0];
2187
2769
 
2188
2770
  ptr= (char *)string;
2189
 
  uint32_t x= 0;
 
2771
  x= 0;
2190
2772
  while ((retstr= strchr(ptr,',')))
2191
2773
  {
2192
2774
    nptr[x++]= atoi(ptr);
2197
2779
  return count;
2198
2780
}
2199
2781
 
2200
 
void print_conclusions(Conclusions &con)
 
2782
void
 
2783
print_conclusions(Conclusions *con)
2201
2784
{
2202
2785
  printf("Benchmark\n");
2203
 
  if (con.getEngine())
2204
 
    printf("\tRunning for engine %s\n", con.getEngine());
2205
 
 
2206
 
  if (not opt_label.empty() || !opt_auto_generate_sql_type.empty())
 
2786
  if (con->getEngine())
 
2787
    printf("\tRunning for engine %s\n", con->getEngine());
 
2788
  if (!opt_label.empty() || !opt_auto_generate_sql_type.empty())
2207
2789
  {
2208
2790
    const char *ptr= opt_auto_generate_sql_type.c_str() ? opt_auto_generate_sql_type.c_str() : "query";
2209
2791
    printf("\tLoad: %s\n", !opt_label.empty() ? opt_label.c_str() : ptr);
2210
2792
  }
2211
2793
  printf("\tAverage Time took to generate schema and initial data: %ld.%03ld seconds\n",
2212
 
         con.getCreateAvgTiming() / 1000, con.getCreateAvgTiming() % 1000);
 
2794
         con->getCreateAvgTiming() / 1000, con->getCreateAvgTiming() % 1000);
2213
2795
  printf("\tAverage number of seconds to run all queries: %ld.%03ld seconds\n",
2214
 
         con.getAvgTiming() / 1000, con.getAvgTiming() % 1000);
 
2796
         con->getAvgTiming() / 1000, con->getAvgTiming() % 1000);
2215
2797
  printf("\tMinimum number of seconds to run all queries: %ld.%03ld seconds\n",
2216
 
         con.getMinTiming() / 1000, con.getMinTiming() % 1000);
 
2798
         con->getMinTiming() / 1000, con->getMinTiming() % 1000);
2217
2799
  printf("\tMaximum number of seconds to run all queries: %ld.%03ld seconds\n",
2218
 
         con.getMaxTiming() / 1000, con.getMaxTiming() % 1000);
 
2800
         con->getMaxTiming() / 1000, con->getMaxTiming() % 1000);
2219
2801
  printf("\tTotal time for tests: %ld.%03ld seconds\n",
2220
 
         con.getSumOfTime() / 1000, con.getSumOfTime() % 1000);
2221
 
  printf("\tStandard Deviation: %ld.%03ld\n", con.getStdDev() / 1000, con.getStdDev() % 1000);
2222
 
  printf("\tNumber of queries in create queries: %"PRIu64"\n", con.getCreateCount());
 
2802
         con->getSumOfTime() / 1000, con->getSumOfTime() % 1000);
 
2803
  printf("\tStandard Deviation: %ld.%03ld\n", con->getStdDev() / 1000, con->getStdDev() % 1000);
 
2804
  printf("\tNumber of queries in create queries: %"PRIu64"\n", con->getCreateCount());
2223
2805
  printf("\tNumber of clients running queries: %u/%u\n",
2224
 
         con.getUsers(), con.getRealUsers());
 
2806
         con->getUsers(), con->getRealUsers());
2225
2807
  printf("\tNumber of times test was run: %u\n", iterations);
2226
 
  printf("\tAverage number of queries per client: %"PRIu64"\n", con.getAvgRows());
2227
 
 
2228
 
  uint64_t temp_val= failed_update_for_transaction; 
2229
 
  if (temp_val)
2230
 
    printf("\tFailed number of updates %"PRIu64"\n", temp_val);
2231
 
 
 
2808
  printf("\tAverage number of queries per client: %"PRIu64"\n", con->getAvgRows());
2232
2809
  printf("\n");
2233
2810
}
2234
2811
 
2235
 
void print_conclusions_csv(Conclusions &con)
 
2812
void
 
2813
print_conclusions_csv(Conclusions *con)
2236
2814
{
 
2815
  unsigned int x;
2237
2816
  char buffer[HUGE_STRING_LENGTH];
2238
2817
  char label_buffer[HUGE_STRING_LENGTH];
2239
2818
  size_t string_len;
2241
2820
 
2242
2821
  memset(label_buffer, 0, sizeof(label_buffer));
2243
2822
 
2244
 
  if (not opt_label.empty())
 
2823
  if (!opt_label.empty())
2245
2824
  {
2246
2825
    string_len= opt_label.length();
2247
2826
 
2248
 
    for (uint32_t x= 0; x < string_len; x++)
 
2827
    for (x= 0; x < string_len; x++)
2249
2828
    {
2250
2829
      if (temp_label[x] == ',')
2251
2830
        label_buffer[x]= '-';
2253
2832
        label_buffer[x]= temp_label[x] ;
2254
2833
    }
2255
2834
  }
2256
 
  else if (not opt_auto_generate_sql_type.empty())
 
2835
  else if (!opt_auto_generate_sql_type.empty())
2257
2836
  {
2258
2837
    string_len= opt_auto_generate_sql_type.length();
2259
2838
 
2260
 
    for (uint32_t x= 0; x < string_len; x++)
 
2839
    for (x= 0; x < string_len; x++)
2261
2840
    {
2262
2841
      if (opt_auto_generate_sql_type[x] == ',')
2263
2842
        label_buffer[x]= '-';
2273
2852
  snprintf(buffer, HUGE_STRING_LENGTH,
2274
2853
           "%s,%s,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,%ld.%03ld,"
2275
2854
           "%u,%u,%u,%"PRIu64"\n",
2276
 
           con.getEngine() ? con.getEngine() : "", /* Storage engine we ran against */
 
2855
           con->getEngine() ? con->getEngine() : "", /* Storage engine we ran against */
2277
2856
           label_buffer, /* Load type */
2278
 
           con.getAvgTiming() / 1000, con.getAvgTiming() % 1000, /* Time to load */
2279
 
           con.getMinTiming() / 1000, con.getMinTiming() % 1000, /* Min time */
2280
 
           con.getMaxTiming() / 1000, con.getMaxTiming() % 1000, /* Max time */
2281
 
           con.getSumOfTime() / 1000, con.getSumOfTime() % 1000, /* Total time */
2282
 
           con.getStdDev() / 1000, con.getStdDev() % 1000, /* Standard Deviation */
 
2857
           con->getAvgTiming() / 1000, con->getAvgTiming() % 1000, /* Time to load */
 
2858
           con->getMinTiming() / 1000, con->getMinTiming() % 1000, /* Min time */
 
2859
           con->getMaxTiming() / 1000, con->getMaxTiming() % 1000, /* Max time */
 
2860
           con->getSumOfTime() / 1000, con->getSumOfTime() % 1000, /* Total time */
 
2861
           con->getStdDev() / 1000, con->getStdDev() % 1000, /* Standard Deviation */
2283
2862
           iterations, /* Iterations */
2284
 
           con.getUsers(), /* Children used max_timing */
2285
 
           con.getRealUsers(), /* Children used max_timing */
2286
 
           con.getAvgRows()  /* Queries run */
 
2863
           con->getUsers(), /* Children used max_timing */
 
2864
           con->getRealUsers(), /* Children used max_timing */
 
2865
           con->getAvgRows()  /* Queries run */
2287
2866
           );
2288
2867
  size_t buff_len= strlen(buffer);
2289
2868
  ssize_t write_ret= write(csv_file, (unsigned char*) buffer, buff_len);
2296
2875
  }
2297
2876
}
2298
2877
 
2299
 
void generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
 
2878
void
 
2879
generate_stats(Conclusions *con, OptionString *eng, Stats *sptr)
2300
2880
{
2301
2881
  Stats *ptr;
2302
 
  uint32_t x;
 
2882
  unsigned int x;
2303
2883
 
2304
2884
  con->setMinTiming(sptr->getTiming());
2305
2885
  con->setMaxTiming(sptr->getTiming());
2329
2909
  else
2330
2910
    con->setEngine(NULL);
2331
2911
 
2332
 
  standard_deviation(*con, sptr);
 
2912
  standard_deviation(con, sptr);
2333
2913
 
2334
2914
  /* Now we do the create time operations */
2335
2915
  con->setCreateMinTiming(sptr->getCreateTiming());
2365
2945
  }
2366
2946
}
2367
2947
 
2368
 
void statement_cleanup(Statement *stmt)
 
2948
void
 
2949
statement_cleanup(Statement *stmt)
2369
2950
{
2370
2951
  Statement *ptr, *nptr;
2371
 
  if (not stmt)
 
2952
  if (!stmt)
2372
2953
    return;
2373
2954
 
2374
2955
  for (ptr= stmt; ptr; ptr= nptr)
2378
2959
  }
2379
2960
}
2380
2961
 
2381
 
void slap_close(drizzle_con_st &con)
 
2962
void
 
2963
slap_close(drizzle_con_st *con)
2382
2964
{
2383
 
  drizzle_free(drizzle_con_drizzle(&con));
 
2965
  if (opt_only_print)
 
2966
    return;
 
2967
 
 
2968
  drizzle_free(drizzle_con_drizzle(con));
2384
2969
}
2385
2970
 
2386
 
void slap_connect(drizzle_con_st &con, bool connect_to_schema)
 
2971
void
 
2972
slap_connect(drizzle_con_st *con, bool connect_to_schema)
2387
2973
{
2388
2974
  /* Connect to server */
2389
2975
  static uint32_t connection_retry_sleep= 100000; /* Microseconds */
2391
2977
  drizzle_return_t ret;
2392
2978
  drizzle_st *drizzle;
2393
2979
 
 
2980
  if (opt_only_print)
 
2981
    return;
 
2982
 
2394
2983
  if (opt_delayed_start)
2395
2984
    usleep(random()%opt_delayed_start);
2396
2985
 
2397
2986
  if ((drizzle= drizzle_create(NULL)) == NULL ||
2398
 
      drizzle_con_add_tcp(drizzle, &con, host.c_str(), opt_drizzle_port,
 
2987
      drizzle_con_add_tcp(drizzle, con, host.c_str(), opt_drizzle_port,
2399
2988
        user.c_str(),
2400
2989
        opt_password.c_str(),
2401
2990
        connect_to_schema ? create_schema_string.c_str() : NULL,
2402
2991
        use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL) == NULL)
2403
2992
  {
2404
 
    fprintf(stderr,"%s: Error creating drizzle object\n", SLAP_NAME);
2405
 
    abort();
 
2993
    fprintf(stderr,"%s: Error creating drizzle object\n", internal::my_progname);
 
2994
    exit(1);
2406
2995
  }
2407
2996
 
2408
 
  drizzle_set_context(drizzle, (void*)(connection_count.fetch_and_increment()));
2409
 
 
2410
 
  if (opt_only_print)
2411
 
    return;
2412
 
 
2413
2997
  for (uint32_t x= 0; x < 10; x++)
2414
2998
  {
2415
 
    if ((ret= drizzle_con_connect(&con)) == DRIZZLE_RETURN_OK)
 
2999
    if ((ret= drizzle_con_connect(con)) == DRIZZLE_RETURN_OK)
2416
3000
    {
2417
3001
      /* Connect suceeded */
2418
3002
      connect_error= 0;
2422
3006
  }
2423
3007
  if (connect_error)
2424
3008
  {
2425
 
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n", SLAP_NAME,
2426
 
            ret, drizzle_con_error(&con));
2427
 
    abort();
 
3009
    fprintf(stderr,"%s: Error when connecting to server: %d %s\n", internal::my_progname,
 
3010
            ret, drizzle_con_error(con));
 
3011
    exit(1);
2428
3012
  }
 
3013
 
 
3014
  return;
2429
3015
}
2430
3016
 
2431
 
void standard_deviation(Conclusions &con, Stats *sptr)
 
3017
void
 
3018
standard_deviation (Conclusions *con, Stats *sptr)
2432
3019
{
 
3020
  unsigned int x;
2433
3021
  long int sum_of_squares;
2434
3022
  double the_catch;
2435
3023
  Stats *ptr;
2436
3024
 
2437
3025
  if (iterations == 1 || iterations == 0)
2438
3026
  {
2439
 
    con.setStdDev(0);
 
3027
    con->setStdDev(0);
2440
3028
    return;
2441
3029
  }
2442
3030
 
2443
 
  uint32_t x;
2444
3031
  for (ptr= sptr, x= 0, sum_of_squares= 0; x < iterations; ptr++, x++)
2445
3032
  {
2446
3033
    long int deviation;
2447
3034
 
2448
 
    deviation= ptr->getTiming() - con.getAvgTiming();
 
3035
    deviation= ptr->getTiming() - con->getAvgTiming();
2449
3036
    sum_of_squares+= deviation*deviation;
2450
3037
  }
2451
3038
 
2452
3039
  the_catch= sqrt((double)(sum_of_squares/(iterations -1)));
2453
 
  con.setStdDev((long int)the_catch);
 
3040
  con->setStdDev((long int)the_catch);
2454
3041
}