~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleslap.cc

  • Committer: David Shrewsbury
  • Date: 2010-08-27 13:02:11 UTC
  • mfrom: (1733 trunk)
  • mto: (1734.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1735.
  • Revision ID: shrewsbury.dave@gmail.com-20100827130211-11vkj8w63l1xhtu8
MergeĀ fromĀ trunk

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