should be it
This commit is contained in:
323
external/duckdb/third_party/tpce-tool/main/EGenValidate.cpp
vendored
Normal file
323
external/duckdb/third_party/tpce-tool/main/EGenValidate.cpp
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Legal Notice
|
||||
*
|
||||
* This document and associated source code (the "Work") is a part of a
|
||||
* benchmark specification maintained by the TPC.
|
||||
*
|
||||
* The TPC reserves all right, title, and interest to the Work as provided
|
||||
* under U.S. and international laws, including without limitation all patent
|
||||
* and trademark rights therein.
|
||||
*
|
||||
* No Warranty
|
||||
*
|
||||
* 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION
|
||||
* CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE
|
||||
* AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER
|
||||
* WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
|
||||
* INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES,
|
||||
* DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF
|
||||
* WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE.
|
||||
* ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT,
|
||||
* QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT
|
||||
* WITH REGARD TO THE WORK.
|
||||
* 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO
|
||||
* ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE
|
||||
* COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS
|
||||
* OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT,
|
||||
* INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY,
|
||||
* OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT
|
||||
* RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD
|
||||
* ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* Contributors
|
||||
* - Christopher Chan-Nui
|
||||
*/
|
||||
|
||||
/*
|
||||
* - 0.3 - Tue Oct 3 23:39:48 CDT 2006
|
||||
* Extracted BucketSimulator class
|
||||
* Extracted string parsing and format functions
|
||||
* Re-vamped to use new threading
|
||||
*
|
||||
* - 0.2 - Mon Sep 11 09:06:35 CDT 2006
|
||||
* Incorporated Matthew Emmerton's suggestions:
|
||||
* Fixed calculation of simorders (was off by 60)
|
||||
* Base GlobalLock on CSyncLock
|
||||
*
|
||||
* - 0.1 - Fri Sep 8 14:26:00 CDT 2006
|
||||
* Initial release
|
||||
*/
|
||||
|
||||
#include "utilities/threading.h"
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "main/EGenLoader_stdafx.h"
|
||||
#include "utilities/DateTime.h"
|
||||
#include "main/progressmeter.h"
|
||||
#include "main/bucketsimulator.h"
|
||||
#include "main/strutil.h"
|
||||
|
||||
using TPCE::int64totimestr;
|
||||
using TPCE::strtodbl;
|
||||
using TPCE::strtoint64;
|
||||
using TPCE::timestrtoint64;
|
||||
|
||||
using TPCE::CCustomerSelection;
|
||||
using TPCE::CRandom;
|
||||
using TPCE::eCustomerTier;
|
||||
using TPCE::iDefaultLoadUnitSize;
|
||||
using TPCE::RNGSEED;
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Helper class to contain the run configuration options
|
||||
class BucketSimOptions {
|
||||
public:
|
||||
int verbose;
|
||||
int helplevel;
|
||||
RNGSEED base_seed;
|
||||
TIdent cust_count;
|
||||
double tpse;
|
||||
bool use_stddev;
|
||||
double stddev;
|
||||
INT64 run_length;
|
||||
UINT sim_count;
|
||||
UINT sim_first;
|
||||
UINT num_threads;
|
||||
UINT interval_time;
|
||||
|
||||
// Calculate the number orders for this simulation
|
||||
INT64 calc_simorders() {
|
||||
return static_cast<INT64>(tpse * static_cast<double>(run_length));
|
||||
}
|
||||
|
||||
BucketSimOptions()
|
||||
: verbose(0), helplevel(0), base_seed(TPCE::RNGSeedBaseTxnInputGenerator), cust_count(0), tpse(10),
|
||||
use_stddev(false), stddev(0), run_length(7200), sim_count(10000), sim_first(0), num_threads(1),
|
||||
interval_time(10) {
|
||||
}
|
||||
};
|
||||
|
||||
// Usage message
|
||||
void usage(const char *progname, BucketSimOptions &options, bool usage_error = true) {
|
||||
cout << "Usage: " << progname << " [options] stddev custcount [TPS-E] [runtime]" << endl
|
||||
<< " -h This help message (-hh for more options)" << endl
|
||||
<< " -v Increase verbosity" << endl
|
||||
<< " -c num Number of customers to simulate (" << options.cust_count << ")" << endl
|
||||
<< " -r runtime Runtime to simulate (" << options.run_length << ")" << endl
|
||||
<< " -e tpsE tpsE to simulate (" << options.tpse << ")" << endl
|
||||
<< " -s stddev Standard Deviation to check against (none)" << endl
|
||||
<< " -t threads Number of threads to use (" << options.num_threads << ")" << endl;
|
||||
if (options.helplevel > 1) {
|
||||
cout << " -S seed Base Seed for random number generation (" << options.base_seed << ")" << endl
|
||||
<< " -n num Number of simulations to perform (" << options.sim_count << ")" << endl
|
||||
<< " -i num Initial simulation number to start with (" << options.sim_first << ")" << endl
|
||||
<< " -u num Progress report interval (" << options.interval_time << ")" << endl;
|
||||
}
|
||||
exit(usage_error ? ERROR_BAD_OPTION : 0);
|
||||
}
|
||||
|
||||
// Parse command line, put discovered values into the options parameter
|
||||
void parseCommandLine(int argc, const char *argv[], BucketSimOptions &options) {
|
||||
char flag = '-';
|
||||
try {
|
||||
bool tpse_set = false;
|
||||
options.tpse = 0;
|
||||
int argnum;
|
||||
for (argnum = 1; argnum < argc; ++argnum) {
|
||||
const char *ptr = argv[argnum];
|
||||
if (*ptr++ != '-') {
|
||||
break;
|
||||
}
|
||||
while (*ptr) {
|
||||
flag = *ptr++;
|
||||
|
||||
// Prefetch an "argument" for the option in case it is needed
|
||||
// later
|
||||
bool use_arg = true;
|
||||
int arg_advance = 0;
|
||||
const char *arg = ptr;
|
||||
// If the argument is not bundled with the options' switch we
|
||||
// use the next argument.
|
||||
if (*ptr == '\0') {
|
||||
arg_advance = 1;
|
||||
arg = argv[argnum + 1];
|
||||
if (arg == NULL) {
|
||||
// If there wasn't an argument pretend it was just an
|
||||
// empty string
|
||||
arg = "";
|
||||
}
|
||||
}
|
||||
|
||||
switch (flag) {
|
||||
case 'v':
|
||||
use_arg = false;
|
||||
options.verbose += 1;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
use_arg = false;
|
||||
options.helplevel += 1;
|
||||
break;
|
||||
case 'S':
|
||||
options.base_seed = (RNGSEED)strtoint64(arg);
|
||||
break;
|
||||
case 'c':
|
||||
options.cust_count = strtoint64(arg);
|
||||
break;
|
||||
case 'n':
|
||||
options.sim_count = static_cast<UINT>(strtoint64(arg));
|
||||
break;
|
||||
case 'i':
|
||||
options.sim_first = static_cast<UINT>(strtoint64(arg));
|
||||
break;
|
||||
case 'r':
|
||||
options.run_length = timestrtoint64(arg);
|
||||
break;
|
||||
case 'e':
|
||||
tpse_set = true;
|
||||
options.tpse = strtodbl(arg);
|
||||
break;
|
||||
case 't':
|
||||
options.num_threads = static_cast<UINT>(strtoint64(arg));
|
||||
break;
|
||||
case 's':
|
||||
options.use_stddev = true;
|
||||
options.stddev = strtodbl(arg);
|
||||
break;
|
||||
case 'u':
|
||||
options.interval_time = static_cast<UINT>(timestrtoint64(arg));
|
||||
options.verbose += 1;
|
||||
break;
|
||||
default:
|
||||
std::ostringstream strm;
|
||||
throw std::runtime_error(std::string("Unknown option"));
|
||||
}
|
||||
|
||||
// If we used an argument we need to consume it
|
||||
if (use_arg) {
|
||||
argnum += arg_advance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// After all the switches are processed we consume the rest of the
|
||||
// command line as positional options
|
||||
if (argnum < argc) {
|
||||
options.use_stddev = true;
|
||||
options.stddev = strtodbl(argv[argnum++]);
|
||||
}
|
||||
if (argnum < argc) {
|
||||
flag = 'c';
|
||||
options.cust_count = strtoint64(argv[argnum++]);
|
||||
}
|
||||
if (argnum < argc) {
|
||||
flag = 't';
|
||||
tpse_set = true;
|
||||
options.tpse = strtodbl(argv[argnum++]);
|
||||
}
|
||||
if (argnum < argc) {
|
||||
flag = 'r';
|
||||
options.run_length = static_cast<UINT>(timestrtoint64(argv[argnum++]));
|
||||
}
|
||||
if (argnum < argc) {
|
||||
cout << "Too many command line arguments!" << endl;
|
||||
usage(argv[0], options);
|
||||
}
|
||||
|
||||
if (!tpse_set) {
|
||||
options.tpse = options.cust_count / 500.0; // 500 is scale factor
|
||||
}
|
||||
|
||||
// If no customers were specified that probably means the user
|
||||
// didn't know how to invoke us.
|
||||
if (options.helplevel || options.cust_count == 0 || !options.use_stddev) {
|
||||
usage(argv[0], options, false);
|
||||
}
|
||||
} catch (std::exception &e) {
|
||||
cout << "Error parsing command line option '" << flag << "': " << e.what() << endl;
|
||||
usage(argv[0], options);
|
||||
exit(ERROR_BAD_OPTION);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
try {
|
||||
TPCE::CDateTime start_time;
|
||||
BucketSimOptions options;
|
||||
std::vector<TPCE::Thread<TPCE::BucketSimulator> *> threads;
|
||||
|
||||
// Output EGen version
|
||||
TPCE::PrintEGenVersion();
|
||||
|
||||
parseCommandLine(argc, argv, options);
|
||||
|
||||
TPCE::BucketProgress progress(options.stddev, options.sim_count, options.verbose);
|
||||
progress.set_display_interval(options.interval_time);
|
||||
|
||||
// Start up simulation threads
|
||||
unsigned int sim_idx = 0;
|
||||
unsigned int sims_per_thread = options.sim_count / options.num_threads + 1;
|
||||
|
||||
while (sim_idx < options.sim_count) {
|
||||
// Last thread only processes however many are left over
|
||||
if (sims_per_thread > options.sim_count - sim_idx) {
|
||||
sims_per_thread = options.sim_count - sim_idx;
|
||||
}
|
||||
TPCE::Thread<TPCE::BucketSimulator> *thr =
|
||||
new TPCE::Thread<TPCE::BucketSimulator>(std::unique_ptr<TPCE::BucketSimulator>(
|
||||
new TPCE::BucketSimulator(options.sim_first + sim_idx, sims_per_thread, options.cust_count,
|
||||
options.calc_simorders(), options.base_seed, progress)));
|
||||
;
|
||||
thr->start();
|
||||
threads.push_back(thr);
|
||||
sim_idx += sims_per_thread;
|
||||
}
|
||||
|
||||
// Wait for all threads and find maximum standard deviation
|
||||
while (!threads.empty()) {
|
||||
TPCE::Thread<TPCE::BucketSimulator> *thr = threads.back();
|
||||
threads.pop_back();
|
||||
thr->stop();
|
||||
delete thr;
|
||||
}
|
||||
|
||||
TPCE::CDateTime now;
|
||||
cout << "Maximum Standard Deviation = " << progress.max_stddev() << endl;
|
||||
cout << "Requested Standard Deviation = " << options.stddev << endl;
|
||||
cout << "Customer Count = " << options.cust_count << endl;
|
||||
cout << "Iteration Count = " << options.sim_count << endl;
|
||||
cout << "Iteration Start = " << options.sim_first << endl;
|
||||
cout << "Iterations Completed = " << progress.current() << endl;
|
||||
cout << "Base Seed = " << options.base_seed << endl;
|
||||
cout << "Simulation Duration = " << options.run_length << endl;
|
||||
cout << "tpsE = " << options.tpse << endl;
|
||||
cout << "Simulation Duration = " << int64totimestr(now.DiffInMilliSeconds(start_time) / 1000) << endl;
|
||||
cout << "Simulation completed at = " << now.ToStr(11) << endl;
|
||||
cout << endl;
|
||||
|
||||
// Test against supplied standard deviation
|
||||
if (progress.max_stddev() < options.stddev) {
|
||||
cout << "Failed!" << endl;
|
||||
exit(4); // Need a constant for this
|
||||
} else {
|
||||
cout << "Passed!" << endl;
|
||||
}
|
||||
|
||||
// Successful run, exit nicely
|
||||
return 0;
|
||||
} catch (std::exception &e) {
|
||||
cout << "Caught exception: " << e.what() << endl;
|
||||
} catch (...) {
|
||||
cout << "Caught unknown exception" << endl;
|
||||
}
|
||||
// Failed run make sure we exit with an error
|
||||
exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user