~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleslap.cc

  • Committer: Brian Aker
  • Date: 2010-08-18 23:12:07 UTC
  • mto: This revision was merged to the branch mainline in revision 1719.
  • Revision ID: brian@tangent.org-20100818231207-2dgclr6o06q90np1
Test scoped ptr in the tree.

Show diffs side-by-side

added added

removed removed

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