should be it
This commit is contained in:
373
external/duckdb/third_party/tpce-tool/main/AddressTable.cpp
vendored
Normal file
373
external/duckdb/third_party/tpce-tool/main/AddressTable.cpp
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* 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
|
||||
* - Sergey Vasilevskiy
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/EGenTables_stdafx.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
const UINT iUSACtryCode = 1; // must be the same as the code in country tax rates file
|
||||
const UINT iCanadaCtryCode = 2; // must be the same as the code in country tax rates file
|
||||
|
||||
// Minimum and maximum to use when generating address street numbers.
|
||||
const int iStreetNumberMin = 100;
|
||||
const int iStreetNumberMax = 25000;
|
||||
|
||||
// Some customers have an AD_LINE_2, some are NULL.
|
||||
const int iPctCustomersWithNullAD_LINE_2 = 60;
|
||||
|
||||
// Of the customers that have an AD_LINE_2, some are
|
||||
// an apartment, others are a suite.
|
||||
const int iPctCustomersWithAptAD_LINE_2 = 75;
|
||||
|
||||
// Minimum and maximum to use when generating apartment numbers.
|
||||
const int iApartmentNumberMin = 1;
|
||||
const int iApartmentNumberMax = 1000;
|
||||
|
||||
// Minimum and maximum to use when generating suite numbers.
|
||||
const int iSuiteNumberMin = 1;
|
||||
const int iSuiteNumberMax = 500;
|
||||
|
||||
// Number of RNG calls to skip for one row in order
|
||||
// to not use any of the random values from the previous row.
|
||||
const int iRNGSkipOneRowAddress = 10; // real number in 3.5: 7
|
||||
|
||||
/*
|
||||
* Constructor for the ADDRESS table class.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN inputFiles - input flat files loaded in memory
|
||||
* IN iCustomerCount - number of customers to generate
|
||||
* IN iStartFromCustomer - ordinal position of the first customer in
|
||||
* the sequence (Note: 1-based) for whom to generate the addresses. Used if
|
||||
* generating customer addresses only. IN bCustomerAddressesOnly - if true,
|
||||
* generate only customer addresses if false, generate exchange, company, and
|
||||
* customer addresses (always start from the first customer in this case)
|
||||
*/
|
||||
CAddressTable::CAddressTable(const DataFileManager &dfm, TIdent iCustomerCount, TIdent iStartFromCustomer,
|
||||
bool bCustomerAddressesOnly, bool bCacheEnabled)
|
||||
: TableTemplate<ADDRESS_ROW>(), m_companies(dfm.CompanyFile()), m_Street(dfm.StreetNameDataFile()),
|
||||
m_StreetSuffix(dfm.StreetSuffixDataFile()), m_ZipCode(dfm.ZipCodeDataFile()),
|
||||
m_iStartFromCustomer(iStartFromCustomer), m_iCustomerCount(iCustomerCount),
|
||||
m_bCustomerAddressesOnly(bCustomerAddressesOnly), m_bCustomerAddress(bCustomerAddressesOnly),
|
||||
m_bCacheEnabled(bCacheEnabled), INVALID_CACHE_ENTRY(-1) {
|
||||
m_iExchangeCount = dfm.ExchangeDataFile().size(); // number of rows in Exchange
|
||||
m_iCompanyCount = m_companies.GetConfiguredCompanyCount(); // number of configured companies
|
||||
|
||||
// Generate customer addresses only (used for CUSTOMER_TAXRATE)
|
||||
if (bCustomerAddressesOnly) {
|
||||
// skip exchanges and companies
|
||||
m_iLastRowNumber = m_iExchangeCount + m_iCompanyCount + iStartFromCustomer - 1;
|
||||
|
||||
// This is not really a count, but the last address row to generate.
|
||||
//
|
||||
m_iTotalAddressCount = m_iLastRowNumber + m_iCustomerCount;
|
||||
} else { // Generating not only customer, but also exchange and company
|
||||
// addresses
|
||||
m_iLastRowNumber = iStartFromCustomer - 1;
|
||||
|
||||
// This is not really a count, but the last address row to generate.
|
||||
//
|
||||
m_iTotalAddressCount = m_iLastRowNumber + m_iCustomerCount + m_iExchangeCount + m_iCompanyCount;
|
||||
}
|
||||
|
||||
m_row.AD_ID = m_iLastRowNumber + iTIdentShift; // extend to 64 bits for address id
|
||||
|
||||
if (m_bCacheEnabled) {
|
||||
m_iCacheSize = (int)iDefaultLoadUnitSize;
|
||||
m_iCacheOffset = iTIdentShift + m_iExchangeCount + m_iCompanyCount + m_iStartFromCustomer;
|
||||
m_CacheZipCode = new int[m_iCacheSize];
|
||||
for (int i = 0; i < m_iCacheSize; i++) {
|
||||
m_CacheZipCode[i] = INVALID_CACHE_ENTRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAddressTable::~CAddressTable() {
|
||||
if (m_bCacheEnabled) {
|
||||
delete[] m_CacheZipCode;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the state for the next load unit.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CAddressTable::InitNextLoadUnit() {
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedTableDefault, (RNGSEED)m_iLastRowNumber * iRNGSkipOneRowAddress));
|
||||
|
||||
ClearRecord(); // this is needed for EGenTest to work
|
||||
|
||||
if (m_bCacheEnabled) {
|
||||
m_iCacheOffset += iDefaultLoadUnitSize;
|
||||
for (int i = 0; i < m_iCacheSize; i++) {
|
||||
m_CacheZipCode[i] = INVALID_CACHE_ENTRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates the next A_ID value.
|
||||
* It is stored in the internal record structure and also returned.
|
||||
* The number of rows generated is incremented. This is why
|
||||
* this function cannot be called more than once for a record.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* next address id.
|
||||
*/
|
||||
TIdent CAddressTable::GenerateNextAD_ID() {
|
||||
// Reset RNG at Load Unit boundary, so that all data is repeatable.
|
||||
//
|
||||
if (m_iLastRowNumber > (m_iExchangeCount + m_iCompanyCount) &&
|
||||
((m_iLastRowNumber - (m_iExchangeCount + m_iCompanyCount)) % iDefaultLoadUnitSize == 0)) {
|
||||
InitNextLoadUnit();
|
||||
}
|
||||
|
||||
++m_iLastRowNumber;
|
||||
// Find out whether this next row is for a customer (so as to generate
|
||||
// AD_LINE_2). Exchange and Company addresses are before Customer ones.
|
||||
//
|
||||
m_bCustomerAddress = m_iLastRowNumber >= m_iExchangeCount + m_iCompanyCount;
|
||||
|
||||
// update state info
|
||||
m_bMoreRecords = m_iLastRowNumber < m_iTotalAddressCount;
|
||||
|
||||
m_row.AD_ID = m_iLastRowNumber + iTIdentShift;
|
||||
|
||||
return m_row.AD_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the address id of the customer specified by the customer id.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN C_ID - customer id (1-based)
|
||||
*
|
||||
* RETURNS:
|
||||
* address id.
|
||||
*/
|
||||
TIdent CAddressTable::GetAD_IDForCustomer(TIdent C_ID) {
|
||||
return m_iExchangeCount + m_iCompanyCount + C_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate AD_LINE_1 and store it in the record structure.
|
||||
* Does not increment the number of rows generated.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CAddressTable::GenerateAD_LINE_1() {
|
||||
int iStreetNum = m_rnd.RndIntRange(iStreetNumberMin, iStreetNumberMax);
|
||||
// int iStreetThreshold = m_rnd.RndIntRange(0,
|
||||
// m_Street->GetGreatestKey()-2);
|
||||
int iStreetThreshold = m_rnd.RndIntRange(0, m_Street.size() - 2);
|
||||
int iStreetSuffixThreshold = m_rnd.RndIntRange(0, m_StreetSuffix.size() - 1);
|
||||
|
||||
snprintf(m_row.AD_LINE1, sizeof(m_row.AD_LINE1), "%d %s %s", iStreetNum, m_Street[iStreetThreshold].STREET_CSTR(),
|
||||
m_StreetSuffix[iStreetSuffixThreshold].SUFFIX_CSTR());
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate AD_LINE_2 and store it in the record structure.
|
||||
* Does not increment the number of rows generated.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CAddressTable::GenerateAD_LINE_2() {
|
||||
if (!m_bCustomerAddress || m_rnd.RndPercent(iPctCustomersWithNullAD_LINE_2)) { // Generate second address line
|
||||
// only for customers (not
|
||||
// companies)
|
||||
m_row.AD_LINE2[0] = '\0';
|
||||
} else {
|
||||
if (m_rnd.RndPercent(iPctCustomersWithAptAD_LINE_2)) {
|
||||
snprintf(m_row.AD_LINE2, sizeof(m_row.AD_LINE2), "Apt. %d",
|
||||
m_rnd.RndIntRange(iApartmentNumberMin, iApartmentNumberMax));
|
||||
} else {
|
||||
snprintf(m_row.AD_LINE2, sizeof(m_row.AD_LINE2), "Suite %d",
|
||||
m_rnd.RndIntRange(iSuiteNumberMin, iSuiteNumberMax));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For a given address id returns the same Threshold used to
|
||||
* select the town, division, zip, and country.
|
||||
* Needed to return a specific division/country for a given address id (for
|
||||
* customer tax rates).
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN ADID - address id
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
int CAddressTable::GetTownDivisionZipCodeThreshold(TIdent ADID) {
|
||||
RNGSEED OldSeed;
|
||||
int iThreshold;
|
||||
|
||||
OldSeed = m_rnd.GetSeed();
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseTownDivZip, (RNGSEED)ADID));
|
||||
iThreshold = m_rnd.RndIntRange(0, m_ZipCode.size() - 1);
|
||||
m_rnd.SetSeed(OldSeed);
|
||||
return (iThreshold);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the country code code for a given zip code.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN szZipCode - string with a US or Canada zip code
|
||||
*
|
||||
* RETURNS:
|
||||
* country code.
|
||||
*/
|
||||
UINT CAddressTable::GetCountryCode(const char *szZipCode) {
|
||||
if (('0' <= szZipCode[0]) && (szZipCode[0] <= '9')) {
|
||||
// If the zip code starts with a number, then it's a USA code.
|
||||
return (iUSACtryCode);
|
||||
} else {
|
||||
// If the zip code does NOT start with a number, than it's a Canadian
|
||||
// code.
|
||||
return (iCanadaCtryCode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a certain division/country code (from the input file) for a given
|
||||
* address id. Used in the loader to properly calculate tax on a trade.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN AD_ID - address id
|
||||
* OUT iDivCode - division (state/province) code
|
||||
* OUT iCtryCode - country (USA/CANADA) code
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CAddressTable::GetDivisionAndCountryCodesForAddress(TIdent AD_ID, UINT &iDivCode, UINT &iCtryCode) {
|
||||
// const TZipCodeInputRow* pZipCodeInputRow = NULL;
|
||||
|
||||
// We will sometimes get AD_ID values that are outside the current
|
||||
// load unit (cached range). We need to check for this case
|
||||
// and avoid the lookup (as we will segfault or get bogus data.)
|
||||
TIdent index = AD_ID - m_iCacheOffset;
|
||||
bool bCheckCache = (index >= 0 && index <= m_iCacheSize);
|
||||
|
||||
if (m_bCacheEnabled && bCheckCache && (INVALID_CACHE_ENTRY != m_CacheZipCode[index])) {
|
||||
// Make use of the cache to get the data.
|
||||
iDivCode = m_ZipCode[m_CacheZipCode[index]].DivisionTaxKey();
|
||||
iCtryCode = GetCountryCode(m_ZipCode[m_CacheZipCode[index]].ZC_CODE_CSTR());
|
||||
|
||||
// We're done, so bail out.
|
||||
return;
|
||||
}
|
||||
|
||||
// The cache wasn't used so get the necessary value.
|
||||
int iThreshold = GetTownDivisionZipCodeThreshold(AD_ID);
|
||||
|
||||
// If possible, cache the result in case we need it again.
|
||||
if (m_bCacheEnabled && bCheckCache) {
|
||||
m_CacheZipCode[index] = iThreshold;
|
||||
}
|
||||
|
||||
// Get the data.
|
||||
iDivCode = m_ZipCode[iThreshold].DivisionTaxKey();
|
||||
iCtryCode = GetCountryCode(m_ZipCode[iThreshold].ZC_CODE_CSTR());
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate zip code and country for the current address id
|
||||
* and store them in the record structure.
|
||||
* Does not increment the number of rows generated.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CAddressTable::GenerateAD_ZC_CODE_CTRY() {
|
||||
int iThreshold;
|
||||
|
||||
iThreshold = GetTownDivisionZipCodeThreshold(m_row.AD_ID);
|
||||
const ZipCodeDataFileRecord &dfr = m_ZipCode[iThreshold];
|
||||
|
||||
strncpy(m_row.AD_ZC_CODE, dfr.ZC_CODE_CSTR(), sizeof(m_row.AD_ZC_CODE));
|
||||
|
||||
if (iUSACtryCode == GetCountryCode(dfr.ZC_CODE_CSTR())) { // US state
|
||||
strncpy(m_row.AD_CTRY, "USA", sizeof(m_row.AD_CTRY));
|
||||
} else { // Canadian province
|
||||
strncpy(m_row.AD_CTRY, "CANADA", sizeof(m_row.AD_CTRY));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate all column values for the next row
|
||||
* and store them in the record structure.
|
||||
* Increment the number of rows generated.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* TRUE, if there are more records in the ADDRESS table; FALSE
|
||||
* othewise.
|
||||
*/
|
||||
bool CAddressTable::GenerateNextRecord() {
|
||||
GenerateNextAD_ID();
|
||||
GenerateAD_LINE_1();
|
||||
GenerateAD_LINE_2();
|
||||
GenerateAD_ZC_CODE_CTRY();
|
||||
|
||||
// Return false if all the rows have been generated
|
||||
return (MoreRecords());
|
||||
}
|
||||
150
external/duckdb/third_party/tpce-tool/main/BaseLogger.cpp
vendored
Normal file
150
external/duckdb/third_party/tpce-tool/main/BaseLogger.cpp
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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
|
||||
* - Matt Emmerton
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: This file implements the interface for data logging.
|
||||
******************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "utilities/EGenStandardTypes.h"
|
||||
#include "main/DriverTypes.h"
|
||||
#include "main/DriverParamSettings.h"
|
||||
#include "main/BaseLogger.h"
|
||||
#include "main/BaseLogFormatter.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
char TPCE::szDriverTypeNames[eDriverMax][14] = {"EGenLoader", "EGenDriverAll", "EGenDriverCE", "EGenDriverMEE",
|
||||
"EGenDriverDM"};
|
||||
|
||||
/* Constructor */
|
||||
CBaseLogger::CBaseLogger(eDriverType drvType, INT32 UniqueId, CBaseLogFormatter *pFormatter)
|
||||
: m_pLogFormatter(pFormatter) {
|
||||
char m_Version[32];
|
||||
|
||||
// Get EGen Version
|
||||
GetEGenVersionString(m_Version, sizeof(m_Version));
|
||||
|
||||
// Generate Log Prefix String
|
||||
snprintf(&m_Prefix[0], sizeof(m_Prefix), "%s (%s) %d", szDriverTypeNames[drvType], m_Version, UniqueId);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
bool CBaseLogger::SendToLogger(const char *szPrefix, const char *szMsg) {
|
||||
CDateTime curTime;
|
||||
return SendToLoggerImpl(szPrefix, curTime.ToStr(12), szMsg);
|
||||
}
|
||||
|
||||
// Strings
|
||||
bool CBaseLogger::SendToLogger(const char *str) {
|
||||
return SendToLogger(m_Prefix, str);
|
||||
}
|
||||
bool CBaseLogger::SendToLogger(string str) {
|
||||
return SendToLogger(str.c_str());
|
||||
}
|
||||
|
||||
// Parameter Structures
|
||||
bool CBaseLogger::SendToLogger(CLoaderSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
bool CBaseLogger::SendToLogger(CDriverGlobalSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CDriverCESettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CDriverCEPartitionSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CDriverMEESettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CDriverDMSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CBrokerVolumeSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CCustomerPositionSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CMarketWatchSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CSecurityDetailSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CTradeLookupSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CTradeOrderSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CTradeUpdateSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(CTxnMixGeneratorSettings &parms) {
|
||||
return SendToLogger(m_pLogFormatter->GetLogOutput(parms));
|
||||
}
|
||||
|
||||
bool CBaseLogger::SendToLogger(TDriverCETxnSettings &parms) {
|
||||
bool result = false;
|
||||
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.BV_settings));
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.CP_settings));
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.MW_settings));
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.SD_settings));
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.TL_settings));
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.TO_settings));
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.TU_settings));
|
||||
result |= SendToLogger(m_pLogFormatter->GetLogOutput(parms.TxnMixGenerator_settings));
|
||||
|
||||
return result;
|
||||
}
|
||||
276
external/duckdb/third_party/tpce-tool/main/CE.cpp
vendored
Normal file
276
external/duckdb/third_party/tpce-tool/main/CE.cpp
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson, Matt Emmerton
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of the CE class.
|
||||
* See CE.h for a description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/CE.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
// Initialization that is common for all constructors.
|
||||
void CCE::Initialize(PDriverCETxnSettings pTxnParamSettings) {
|
||||
m_pLogger->SendToLogger(m_DriverGlobalSettings);
|
||||
|
||||
// Always configure the CE with default settings, to ensure that it is
|
||||
// set up properly.
|
||||
SetTxnTunables(&m_DriverCETxnSettings);
|
||||
|
||||
// If user tunables are provided, set them now. If they are invalid, they
|
||||
// will not be used and we will continue to use the defaults set above.
|
||||
if (pTxnParamSettings) {
|
||||
SetTxnTunables(pTxnParamSettings);
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically generate unique RNG seeds.
|
||||
// The CRandom class uses an unsigned 64-bit value for the seed.
|
||||
// This routine automatically generates two unique seeds. One is used for
|
||||
// the TxnInput generator RNG, and the other is for the TxnMixGenerator RNG.
|
||||
// The 64 bits are used as follows.
|
||||
//
|
||||
// Bits 0 - 31 Caller provided unique unsigned 32-bit id.
|
||||
// Bit 32 0 for TxnInputGenerator, 1 for TxnMixGenerator
|
||||
// Bits 33 - 43 Number of days since the base time. The base time
|
||||
// is set to be January 1 of the most recent year that is
|
||||
// a multiple of 5. This allows enough space for the last
|
||||
// field, and it makes the algorithm "timeless" by resetting
|
||||
// the generated values every 5 years.
|
||||
// Bits 44 - 63 Current time of day measured in 1/10's of a second.
|
||||
//
|
||||
void CCE::AutoSetRNGSeeds(UINT32 UniqueId) {
|
||||
CDateTime Now;
|
||||
INT32 BaseYear;
|
||||
INT32 Tmp1, Tmp2;
|
||||
|
||||
Now.GetYMD(&BaseYear, &Tmp1, &Tmp2);
|
||||
|
||||
// Set the base year to be the most recent year that was a multiple of 5.
|
||||
BaseYear -= (BaseYear % 5);
|
||||
CDateTime Base(BaseYear, 1, 1); // January 1st in the BaseYear
|
||||
|
||||
// Initialize the seed with the current time of day measured in 1/10's of a
|
||||
// second. This will use up to 20 bits.
|
||||
RNGSEED Seed;
|
||||
Seed = Now.MSec() / 100;
|
||||
|
||||
// Now add in the number of days since the base time.
|
||||
// The number of days in the 5 year period requires 11 bits.
|
||||
// So shift up by that much to make room in the "lower" bits.
|
||||
Seed <<= 11;
|
||||
Seed += (RNGSEED)((INT64)Now.DayNo() - (INT64)Base.DayNo());
|
||||
|
||||
// So far, we've used up 31 bits.
|
||||
// Save the "last" bit of the "upper" 32 for the RNG id.
|
||||
// In addition, make room for the caller's 32-bit unique id.
|
||||
// So shift a total of 33 bits.
|
||||
Seed <<= 33;
|
||||
|
||||
// Now the "upper" 32-bits have been set with a value for RNG 0.
|
||||
// Add in the sponsor's unique id for the "lower" 32-bits.
|
||||
Seed += UniqueId;
|
||||
|
||||
// Set the TxnMixGenerator RNG to the unique seed.
|
||||
m_TxnMixGenerator.SetRNGSeed(Seed);
|
||||
m_DriverCESettings.cur.TxnMixRNGSeed = Seed;
|
||||
|
||||
// Set the RNG Id to 1 for the TxnInputGenerator.
|
||||
Seed |= UINT64_CONST(0x0000000100000000);
|
||||
m_TxnInputGenerator.SetRNGSeed(Seed);
|
||||
m_DriverCESettings.cur.TxnInputRNGSeed = Seed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor - no partitioning by C_ID, automatic RNG seed generation
|
||||
* (requires unique input)
|
||||
*/
|
||||
CCE::CCE(CCESUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iDaysOfInitialTrades, UINT32 UniqueId,
|
||||
const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_DriverGlobalSettings(iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor, iDaysOfInitialTrades),
|
||||
m_DriverCESettings(UniqueId, 0, 0), m_pSUT(pSUT), m_pLogger(pLogger),
|
||||
m_TxnMixGenerator(&m_DriverCETxnSettings, m_pLogger),
|
||||
m_TxnInputGenerator(dfm, iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor,
|
||||
iDaysOfInitialTrades * HoursPerWorkDay, m_pLogger, &m_DriverCETxnSettings) {
|
||||
m_pLogger->SendToLogger("CE object constructed using constructor 1 (valid "
|
||||
"for publication: YES).");
|
||||
|
||||
Initialize(pDriverCETxnSettings);
|
||||
AutoSetRNGSeeds(UniqueId);
|
||||
|
||||
m_pLogger->SendToLogger(m_DriverCESettings); // log the RNG seeds
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor - no partitioning by C_ID, RNG seeds provided
|
||||
*/
|
||||
CCE::CCE(CCESUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iDaysOfInitialTrades, UINT32 UniqueId,
|
||||
RNGSEED TxnMixRNGSeed, RNGSEED TxnInputRNGSeed, const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_DriverGlobalSettings(iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor, iDaysOfInitialTrades),
|
||||
m_DriverCESettings(UniqueId, TxnMixRNGSeed, TxnInputRNGSeed), m_pSUT(pSUT), m_pLogger(pLogger),
|
||||
m_TxnMixGenerator(&m_DriverCETxnSettings, TxnMixRNGSeed, m_pLogger),
|
||||
m_TxnInputGenerator(dfm, iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor,
|
||||
iDaysOfInitialTrades * HoursPerWorkDay, TxnInputRNGSeed, m_pLogger, &m_DriverCETxnSettings) {
|
||||
m_pLogger->SendToLogger("CE object constructed using constructor 2 (valid "
|
||||
"for publication: NO).");
|
||||
|
||||
Initialize(pDriverCETxnSettings);
|
||||
|
||||
m_pLogger->SendToLogger(m_DriverCESettings); // log the RNG seeds
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor - partitioning by C_ID, automatic RNG seed generation (requires
|
||||
* unique input)
|
||||
*/
|
||||
CCE::CCE(CCESUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, TIdent iMyStartingCustomerId, TIdent iMyCustomerCount, INT32 iPartitionPercent,
|
||||
INT32 iScaleFactor, INT32 iDaysOfInitialTrades, UINT32 UniqueId,
|
||||
const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_DriverGlobalSettings(iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor, iDaysOfInitialTrades),
|
||||
m_DriverCESettings(UniqueId, 0, 0),
|
||||
m_DriverCEPartitionSettings(iMyStartingCustomerId, iMyCustomerCount, iPartitionPercent), m_pSUT(pSUT),
|
||||
m_pLogger(pLogger), m_TxnMixGenerator(&m_DriverCETxnSettings, m_pLogger),
|
||||
m_TxnInputGenerator(dfm, iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor,
|
||||
iDaysOfInitialTrades * HoursPerWorkDay, iMyStartingCustomerId, iMyCustomerCount,
|
||||
iPartitionPercent, m_pLogger, &m_DriverCETxnSettings) {
|
||||
m_pLogger->SendToLogger("CE object constructed using constructor 3 (valid "
|
||||
"for publication: YES).");
|
||||
|
||||
Initialize(pDriverCETxnSettings);
|
||||
AutoSetRNGSeeds(UniqueId);
|
||||
|
||||
m_pLogger->SendToLogger(m_DriverCEPartitionSettings); // log the partition settings
|
||||
m_pLogger->SendToLogger(m_DriverCESettings); // log the RNG seeds
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor - partitioning by C_ID, RNG seeds provided
|
||||
*/
|
||||
CCE::CCE(CCESUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, TIdent iMyStartingCustomerId, TIdent iMyCustomerCount, INT32 iPartitionPercent,
|
||||
INT32 iScaleFactor, INT32 iDaysOfInitialTrades, UINT32 UniqueId, RNGSEED TxnMixRNGSeed,
|
||||
RNGSEED TxnInputRNGSeed, const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_DriverGlobalSettings(iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor, iDaysOfInitialTrades),
|
||||
m_DriverCESettings(UniqueId, TxnMixRNGSeed, TxnInputRNGSeed),
|
||||
m_DriverCEPartitionSettings(iMyStartingCustomerId, iMyCustomerCount, iPartitionPercent), m_pSUT(pSUT),
|
||||
m_pLogger(pLogger), m_TxnMixGenerator(&m_DriverCETxnSettings, TxnMixRNGSeed, m_pLogger),
|
||||
m_TxnInputGenerator(dfm, iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor,
|
||||
iDaysOfInitialTrades * HoursPerWorkDay, iMyStartingCustomerId, iMyCustomerCount,
|
||||
iPartitionPercent, TxnInputRNGSeed, m_pLogger, &m_DriverCETxnSettings) {
|
||||
m_pLogger->SendToLogger("CE object constructed using constructor 4 (valid "
|
||||
"for publication: NO).");
|
||||
|
||||
Initialize(pDriverCETxnSettings);
|
||||
|
||||
m_pLogger->SendToLogger(m_DriverCEPartitionSettings); // log the partition settings
|
||||
m_pLogger->SendToLogger(m_DriverCESettings); // log the RNG seeds
|
||||
}
|
||||
|
||||
CCE::~CCE(void) {
|
||||
m_pLogger->SendToLogger("CE object destroyed.");
|
||||
}
|
||||
|
||||
RNGSEED CCE::GetTxnInputGeneratorRNGSeed(void) {
|
||||
return (m_TxnInputGenerator.GetRNGSeed());
|
||||
}
|
||||
|
||||
RNGSEED CCE::GetTxnMixGeneratorRNGSeed(void) {
|
||||
return (m_TxnMixGenerator.GetRNGSeed());
|
||||
}
|
||||
|
||||
void CCE::SetTxnTunables(const PDriverCETxnSettings pTxnParamSettings) {
|
||||
if (pTxnParamSettings->IsValid()) {
|
||||
// Update Tunables
|
||||
if (pTxnParamSettings != &m_DriverCETxnSettings) // only copy from a different location
|
||||
{
|
||||
m_DriverCETxnSettings = *pTxnParamSettings;
|
||||
}
|
||||
|
||||
// Trigger Runtime Updates
|
||||
m_TxnMixGenerator.UpdateTunables();
|
||||
m_TxnInputGenerator.UpdateTunables();
|
||||
} else {
|
||||
m_pLogger->SendToLogger("ERROR: CCE::SetTxnTunables() failed due to invalid tunables.");
|
||||
}
|
||||
}
|
||||
|
||||
void CCE::DoTxn(void) {
|
||||
int iTxnType = m_TxnMixGenerator.GenerateNextTxnType();
|
||||
|
||||
switch (iTxnType) {
|
||||
case CCETxnMixGenerator::BROKER_VOLUME:
|
||||
m_TxnInputGenerator.GenerateBrokerVolumeInput(m_BrokerVolumeTxnInput);
|
||||
m_pSUT->BrokerVolume(&m_BrokerVolumeTxnInput);
|
||||
break;
|
||||
case CCETxnMixGenerator::CUSTOMER_POSITION:
|
||||
m_TxnInputGenerator.GenerateCustomerPositionInput(m_CustomerPositionTxnInput);
|
||||
m_pSUT->CustomerPosition(&m_CustomerPositionTxnInput);
|
||||
break;
|
||||
case CCETxnMixGenerator::MARKET_WATCH:
|
||||
m_TxnInputGenerator.GenerateMarketWatchInput(m_MarketWatchTxnInput);
|
||||
m_pSUT->MarketWatch(&m_MarketWatchTxnInput);
|
||||
break;
|
||||
case CCETxnMixGenerator::SECURITY_DETAIL:
|
||||
m_TxnInputGenerator.GenerateSecurityDetailInput(m_SecurityDetailTxnInput);
|
||||
m_pSUT->SecurityDetail(&m_SecurityDetailTxnInput);
|
||||
break;
|
||||
case CCETxnMixGenerator::TRADE_LOOKUP:
|
||||
m_TxnInputGenerator.GenerateTradeLookupInput(m_TradeLookupTxnInput);
|
||||
m_pSUT->TradeLookup(&m_TradeLookupTxnInput);
|
||||
break;
|
||||
case CCETxnMixGenerator::TRADE_ORDER:
|
||||
bool bExecutorIsAccountOwner;
|
||||
INT32 iTradeType;
|
||||
m_TxnInputGenerator.GenerateTradeOrderInput(m_TradeOrderTxnInput, iTradeType, bExecutorIsAccountOwner);
|
||||
m_pSUT->TradeOrder(&m_TradeOrderTxnInput, iTradeType, bExecutorIsAccountOwner);
|
||||
break;
|
||||
case CCETxnMixGenerator::TRADE_STATUS:
|
||||
m_TxnInputGenerator.GenerateTradeStatusInput(m_TradeStatusTxnInput);
|
||||
m_pSUT->TradeStatus(&m_TradeStatusTxnInput);
|
||||
break;
|
||||
case CCETxnMixGenerator::TRADE_UPDATE:
|
||||
m_TxnInputGenerator.GenerateTradeUpdateInput(m_TradeUpdateTxnInput);
|
||||
m_pSUT->TradeUpdate(&m_TradeUpdateTxnInput);
|
||||
break;
|
||||
default:
|
||||
cerr << "CE: Generated illegal transaction" << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
960
external/duckdb/third_party/tpce-tool/main/CETxnInputGenerator.cpp
vendored
Normal file
960
external/duckdb/third_party/tpce-tool/main/CETxnInputGenerator.cpp
vendored
Normal file
@@ -0,0 +1,960 @@
|
||||
/*
|
||||
* 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
|
||||
* - Sergey Vasilevskiy, Doug Johnson, Matt Emmerton
|
||||
*/
|
||||
|
||||
#include "main/CETxnInputGenerator.h"
|
||||
#include "main/DailyMarketTable.h"
|
||||
#include "main/TradeTypeIDs.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
/*
|
||||
* Constructor - no partitioning by C_ID.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN dfm - Data file manager
|
||||
* IN iConfiguredCustomerCount - number of configured customers in
|
||||
* the database IN iActiveCustomerCount - number of active customers in
|
||||
* the database IN iScaleFactor - scale factor (number of
|
||||
* customers per 1 tpsE) of the database IN iHoursOfInitialTrades -
|
||||
* number of hours of the initial trades portion of the database IN pLogger -
|
||||
* reference to parameter logging object IN pDriverCETxnSettings -
|
||||
* initial transaction parameter settings
|
||||
*
|
||||
* RETURNS:
|
||||
* not applicable.
|
||||
*/
|
||||
CCETxnInputGenerator::CCETxnInputGenerator(const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iHoursOfInitialTrades,
|
||||
CBaseLogger *pLogger,
|
||||
const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_rnd(RNGSeedBaseTxnInputGenerator) // initialize with a default seed
|
||||
,
|
||||
m_Person(dfm, 0, false), m_CustomerSelection(&m_rnd, iDefaultStartFromCustomer, iActiveCustomerCount),
|
||||
m_AccsAndPerms(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Holdings(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Brokers(dfm, iActiveCustomerCount, iDefaultStartFromCustomer), m_pCompanies(dfm.CompanyFile()),
|
||||
m_pSecurities(dfm.SecurityFile()), m_pIndustries(dfm.IndustryDataFile()), m_pSectors(dfm.SectorDataFile()),
|
||||
m_pStatusType(dfm.StatusTypeDataFile()), m_pTradeType(dfm.TradeTypeDataFile()),
|
||||
m_pDriverCETxnSettings(pDriverCETxnSettings), m_pLogger(pLogger),
|
||||
m_iConfiguredCustomerCount(iConfiguredCustomerCount), m_iActiveCustomerCount(iActiveCustomerCount),
|
||||
m_iMyStartingCustomerId(iDefaultStartFromCustomer), m_iMyCustomerCount(iActiveCustomerCount),
|
||||
m_iPartitionPercent(100), m_iScaleFactor(iScaleFactor), m_iHoursOfInitialTrades(iHoursOfInitialTrades) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor - no partitioning by C_ID, RNG seed provided.
|
||||
*
|
||||
* RNG seed is for testing/engineering work allowing repeatable transaction
|
||||
* parameter stream. This constructor is NOT legal for a benchmark publication.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN dfm - Data file manager
|
||||
* IN iConfiguredCustomerCount - number of configured customers in
|
||||
* the database IN iActiveCustomerCount - number of active customers in
|
||||
* the database IN iScaleFactor - scale factor (number of
|
||||
* customers per 1 tpsE) of the database IN iHoursOfInitialTrades -
|
||||
* number of hours of the initial trades portion of the database IN RNGSeed -
|
||||
* initial seed for random number generator IN pLogger -
|
||||
* reference to parameter logging object IN pDriverCETxnSettings -
|
||||
* initial transaction parameter settings
|
||||
*
|
||||
* RETURNS:
|
||||
* not applicable.
|
||||
*/
|
||||
CCETxnInputGenerator::CCETxnInputGenerator(const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iHoursOfInitialTrades,
|
||||
RNGSEED RNGSeed, CBaseLogger *pLogger,
|
||||
const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_rnd(RNGSeed) // to be predictable
|
||||
,
|
||||
m_Person(dfm, 0, false), m_CustomerSelection(&m_rnd, iDefaultStartFromCustomer, iActiveCustomerCount),
|
||||
m_AccsAndPerms(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Holdings(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Brokers(dfm, iActiveCustomerCount, iDefaultStartFromCustomer), m_pCompanies(dfm.CompanyFile()),
|
||||
m_pSecurities(dfm.SecurityFile()), m_pIndustries(dfm.IndustryDataFile()), m_pSectors(dfm.SectorDataFile()),
|
||||
m_pStatusType(dfm.StatusTypeDataFile()), m_pTradeType(dfm.TradeTypeDataFile()),
|
||||
m_pDriverCETxnSettings(pDriverCETxnSettings), m_pLogger(pLogger),
|
||||
m_iConfiguredCustomerCount(iConfiguredCustomerCount), m_iActiveCustomerCount(iActiveCustomerCount),
|
||||
m_iMyStartingCustomerId(iDefaultStartFromCustomer), m_iMyCustomerCount(iActiveCustomerCount),
|
||||
m_iPartitionPercent(100), m_iScaleFactor(iScaleFactor), m_iHoursOfInitialTrades(iHoursOfInitialTrades) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor - partitioning by C_ID.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN dfm - Data file manager
|
||||
* IN iConfiguredCustomerCount - number of configured customers in
|
||||
* the database IN iActiveCustomerCount - number of active customers in
|
||||
* the database IN iScaleFactor - scale factor (number of
|
||||
* customers per 1 tpsE) of the database IN iHoursOfInitialTrades -
|
||||
* number of hours of the initial trades portion of the database IN
|
||||
* iMyStartingCustomerId - first customer id (1-based) of the partition
|
||||
* for this instance IN iMyCustomerCount - number of customers in
|
||||
* the partition for this instance IN iPartitionPercent - the
|
||||
* percentage of C_IDs generated within this instance's partition IN pLogger -
|
||||
* reference to parameter logging object IN pDriverCETxnSettings -
|
||||
* initial transaction parameter settings
|
||||
*
|
||||
* RETURNS:
|
||||
* not applicable.
|
||||
*/
|
||||
CCETxnInputGenerator::CCETxnInputGenerator(const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iHoursOfInitialTrades,
|
||||
TIdent iMyStartingCustomerId, TIdent iMyCustomerCount,
|
||||
INT32 iPartitionPercent, CBaseLogger *pLogger,
|
||||
const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_rnd(RNGSeedBaseTxnInputGenerator) // initialize with a default seed
|
||||
,
|
||||
m_Person(dfm, 0, false), m_CustomerSelection(&m_rnd, iDefaultStartFromCustomer, iActiveCustomerCount,
|
||||
iPartitionPercent, iMyStartingCustomerId, iMyCustomerCount),
|
||||
m_AccsAndPerms(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Holdings(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Brokers(dfm, iActiveCustomerCount, iDefaultStartFromCustomer), m_pCompanies(dfm.CompanyFile()),
|
||||
m_pSecurities(dfm.SecurityFile()), m_pIndustries(dfm.IndustryDataFile()), m_pSectors(dfm.SectorDataFile()),
|
||||
m_pStatusType(dfm.StatusTypeDataFile()), m_pTradeType(dfm.TradeTypeDataFile()),
|
||||
m_pDriverCETxnSettings(pDriverCETxnSettings), m_pLogger(pLogger),
|
||||
m_iConfiguredCustomerCount(iConfiguredCustomerCount), m_iActiveCustomerCount(iActiveCustomerCount),
|
||||
m_iMyStartingCustomerId(iMyStartingCustomerId), m_iMyCustomerCount(iMyCustomerCount),
|
||||
m_iPartitionPercent(iPartitionPercent), m_iScaleFactor(iScaleFactor),
|
||||
m_iHoursOfInitialTrades(iHoursOfInitialTrades) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor - partitioning by C_ID, RNG seed provided.
|
||||
*
|
||||
* RNG seed is for testing/engineering work allowing repeatable transaction
|
||||
* parameter stream. This constructor is NOT legal for a benchmark publication.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN dfm - Data file manager
|
||||
* IN iConfiguredCustomerCount - number of configured customers in
|
||||
* the database IN iActiveCustomerCount - number of active customers in
|
||||
* the database IN iScaleFactor - scale factor (number of
|
||||
* customers per 1 tpsE) of the database IN iHoursOfInitialTrades -
|
||||
* number of hours of the initial trades portion of the database IN
|
||||
* iMyStartingCustomerId - first customer id (1-based) of the partition
|
||||
* for this instance IN iMyCustomerCount - number of customers in
|
||||
* the partition for this instance IN iPartitionPercent - the
|
||||
* percentage of C_IDs generated within this instance's partition IN pLogger -
|
||||
* reference to parameter logging object IN pDriverCETxnSettings -
|
||||
* initial transaction parameter settings
|
||||
*
|
||||
* RETURNS:
|
||||
* not applicable.
|
||||
*/
|
||||
CCETxnInputGenerator::CCETxnInputGenerator(const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iHoursOfInitialTrades,
|
||||
TIdent iMyStartingCustomerId, TIdent iMyCustomerCount,
|
||||
INT32 iPartitionPercent, RNGSEED RNGSeed, CBaseLogger *pLogger,
|
||||
const PDriverCETxnSettings pDriverCETxnSettings)
|
||||
: m_rnd(RNGSeed) // to be predictable
|
||||
,
|
||||
m_Person(dfm, 0, false), m_CustomerSelection(&m_rnd, iDefaultStartFromCustomer, iActiveCustomerCount,
|
||||
iPartitionPercent, iMyStartingCustomerId, iMyCustomerCount),
|
||||
m_AccsAndPerms(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Holdings(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Brokers(dfm, iActiveCustomerCount, iDefaultStartFromCustomer), m_pCompanies(dfm.CompanyFile()),
|
||||
m_pSecurities(dfm.SecurityFile()), m_pIndustries(dfm.IndustryDataFile()), m_pSectors(dfm.SectorDataFile()),
|
||||
m_pStatusType(dfm.StatusTypeDataFile()), m_pTradeType(dfm.TradeTypeDataFile()),
|
||||
m_pDriverCETxnSettings(pDriverCETxnSettings), m_pLogger(pLogger),
|
||||
m_iConfiguredCustomerCount(iConfiguredCustomerCount), m_iActiveCustomerCount(iActiveCustomerCount),
|
||||
m_iMyStartingCustomerId(iMyStartingCustomerId), m_iMyCustomerCount(iMyCustomerCount),
|
||||
m_iPartitionPercent(iPartitionPercent), m_iScaleFactor(iScaleFactor),
|
||||
m_iHoursOfInitialTrades(iHoursOfInitialTrades) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform initialization common to all constructors.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN pDriverCETxnSettings - initial transaction parameter
|
||||
* settings
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::Initialize() {
|
||||
m_iActiveCompanyCount = m_pCompanies.GetActiveCompanyCount();
|
||||
m_iActiveSecurityCount = m_pSecurities.GetActiveSecurityCount();
|
||||
m_iIndustryCount = m_pIndustries.size();
|
||||
m_iSectorCount = m_pSectors.size();
|
||||
m_iStartFromCompany = m_pCompanies.GetCompanyId(0); // from the first company
|
||||
|
||||
// In order for this computation to overflow an INT64, assuming that all
|
||||
// multiplications are executed before divisions and the default value
|
||||
// for ITD is used, the active customer count must be greater than 2.1e10
|
||||
// (21 billion customers). I hope we never get to that point.
|
||||
// NOTE: (iAbortTrade / 100) = 1.01, which is compensation for rollbacks.
|
||||
|
||||
m_iMaxActivePrePopulatedTradeID = m_iHoursOfInitialTrades;
|
||||
m_iMaxActivePrePopulatedTradeID *= SecondsPerHour;
|
||||
m_iMaxActivePrePopulatedTradeID *= m_iActiveCustomerCount;
|
||||
m_iMaxActivePrePopulatedTradeID /= m_iScaleFactor;
|
||||
m_iMaxActivePrePopulatedTradeID *= iAbortTrade;
|
||||
m_iMaxActivePrePopulatedTradeID /= 100;
|
||||
|
||||
// Set the start time (time 0) to the base time
|
||||
m_StartTime.Set(InitialTradePopulationBaseYear, InitialTradePopulationBaseMonth, InitialTradePopulationBaseDay,
|
||||
InitialTradePopulationBaseHour, InitialTradePopulationBaseMinute, InitialTradePopulationBaseSecond,
|
||||
InitialTradePopulationBaseFraction);
|
||||
|
||||
// UpdateTunables() is called from CCE constructor (Initialize)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return internal random number generator seed.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* current random number generator seed.
|
||||
*/
|
||||
RNGSEED CCETxnInputGenerator::GetRNGSeed(void) {
|
||||
return (m_rnd.GetSeed());
|
||||
}
|
||||
|
||||
/*
|
||||
* Set internal random number generator seed.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN RNGSeed - new random number generator seed
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::SetRNGSeed(RNGSEED RNGSeed) {
|
||||
m_rnd.SetSeed(RNGSeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Refresh internal information from the external transaction parameters.
|
||||
* This function should be called anytime the external transaction
|
||||
* parameter structure changes.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::UpdateTunables(void) {
|
||||
INT64 secondsOfInitialTrades = (INT64)m_iHoursOfInitialTrades * SecondsPerHour;
|
||||
|
||||
m_iTradeLookupFrame2MaxTimeInMilliSeconds =
|
||||
(INT64)(secondsOfInitialTrades - ((INT64)m_pDriverCETxnSettings->TL_settings.cur.BackOffFromEndTimeFrame2)) *
|
||||
MsPerSecond;
|
||||
|
||||
m_iTradeLookupFrame3MaxTimeInMilliSeconds =
|
||||
(INT64)(secondsOfInitialTrades - ((INT64)m_pDriverCETxnSettings->TL_settings.cur.BackOffFromEndTimeFrame3)) *
|
||||
MsPerSecond;
|
||||
|
||||
m_iTradeLookupFrame4MaxTimeInMilliSeconds =
|
||||
(INT64)(secondsOfInitialTrades - ((INT64)m_pDriverCETxnSettings->TL_settings.cur.BackOffFromEndTimeFrame4)) *
|
||||
MsPerSecond;
|
||||
|
||||
m_iTradeUpdateFrame2MaxTimeInMilliSeconds =
|
||||
(INT64)(secondsOfInitialTrades - ((INT64)m_pDriverCETxnSettings->TU_settings.cur.BackOffFromEndTimeFrame2)) *
|
||||
MsPerSecond;
|
||||
|
||||
m_iTradeUpdateFrame3MaxTimeInMilliSeconds =
|
||||
(INT64)(secondsOfInitialTrades - ((INT64)m_pDriverCETxnSettings->TU_settings.cur.BackOffFromEndTimeFrame3)) *
|
||||
MsPerSecond;
|
||||
|
||||
// Set the completion time of the last initial trade.
|
||||
// 15 minutes are added at the end of hours of initial trades for pending
|
||||
// trades.
|
||||
m_EndTime = m_StartTime;
|
||||
m_EndTime.AddWorkMs((INT64)(secondsOfInitialTrades + 15 * SecondsPerMinute) * MsPerSecond);
|
||||
|
||||
// Based on 10 * Trade-Order transaction mix percentage.
|
||||
// This is currently how the mix levels are set, so use that.
|
||||
m_iTradeOrderRollbackLimit = m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeOrderMixLevel;
|
||||
m_iTradeOrderRollbackLevel = m_pDriverCETxnSettings->TO_settings.cur.rollback;
|
||||
|
||||
// Log Tunables
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->BV_settings);
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->CP_settings);
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->MW_settings);
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->SD_settings);
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->TL_settings);
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->TO_settings);
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->TU_settings);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Non-Uniform customer ID.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT iCustomerId - generated C_ID
|
||||
* OUT iCustomerTier - generated C_TIER
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
inline void CCETxnInputGenerator::GenerateNonUniformRandomCustomerId(TIdent &iCustomerId,
|
||||
eCustomerTier &iCustomerTier) {
|
||||
m_CustomerSelection.GenerateRandomCustomer(iCustomerId, iCustomerTier);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate customer account ID (uniformly distributed).
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* CA_ID uniformly distributed across all load units.
|
||||
*/
|
||||
TIdent CCETxnInputGenerator::GenerateRandomCustomerAccountId() {
|
||||
TIdent iCustomerId;
|
||||
TIdent iCustomerAccountId;
|
||||
eCustomerTier iCustomerTier;
|
||||
|
||||
m_CustomerSelection.GenerateRandomCustomer(iCustomerId, iCustomerTier);
|
||||
iCustomerAccountId = m_AccsAndPerms.GenerateRandomAccountId(m_rnd, iCustomerId, iCustomerTier);
|
||||
|
||||
return (iCustomerAccountId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a trade id to be used in Trade-Lookup / Trade-Update Frame 1.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN AValue - parameter to NURAND function
|
||||
* IN SValue - parameter to NURAND function
|
||||
*
|
||||
* RETURNS:
|
||||
* T_ID, distributed non-uniformly.
|
||||
*/
|
||||
TTrade CCETxnInputGenerator::GenerateNonUniformTradeID(INT32 AValue, INT32 SValue) {
|
||||
TTrade TradeId;
|
||||
|
||||
TradeId = m_rnd.NURnd(1, m_iMaxActivePrePopulatedTradeID, AValue, SValue);
|
||||
|
||||
// Skip over trade id's that were skipped over during load time.
|
||||
if (m_Holdings.IsAbortedTrade(TradeId)) {
|
||||
TradeId++;
|
||||
}
|
||||
|
||||
TradeId += iTTradeShift; // shift trade id to 64-bit value
|
||||
|
||||
return (TradeId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a trade timestamp to be used in Trade-Lookup / Trade-Update.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT dts - returned timestamp
|
||||
* IN MaxTimeInMilliSeconds - time interval (from the first initial
|
||||
* trade) in which to generate the timestamp IN AValue -
|
||||
* parameter to NURAND function IN SValue - parameter to
|
||||
* NURAND function
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateNonUniformTradeDTS(TPCE::TIMESTAMP_STRUCT &dts, INT64 MaxTimeInMilliSeconds,
|
||||
INT32 AValue, INT32 SValue) {
|
||||
CDateTime TradeTime(InitialTradePopulationBaseYear, InitialTradePopulationBaseMonth, InitialTradePopulationBaseDay,
|
||||
InitialTradePopulationBaseHour, InitialTradePopulationBaseMinute,
|
||||
InitialTradePopulationBaseSecond,
|
||||
InitialTradePopulationBaseFraction); // NOTE: Interpretting Fraction as
|
||||
// milliseconds,
|
||||
// probably 0 anyway.
|
||||
INT64 TradeTimeOffset;
|
||||
|
||||
// Generate random number of seconds from the base time.
|
||||
//
|
||||
TradeTimeOffset = m_rnd.NURnd(1, MaxTimeInMilliSeconds, AValue, SValue);
|
||||
|
||||
// The time we have is an offset into the initial pre-populated trading
|
||||
// time. This needs to be converted into a "real" time taking into account 8
|
||||
// hour business days, etc.
|
||||
|
||||
TradeTime.AddWorkMs(TradeTimeOffset);
|
||||
TradeTime.GetTimeStamp(&dts);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Broker-Volume transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction.
|
||||
*
|
||||
* RETURNS:
|
||||
* the number of brokers generated.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateBrokerVolumeInput(TBrokerVolumeTxnInput &TxnReq) {
|
||||
INT32 iNumBrokers;
|
||||
INT32 iCount, i;
|
||||
TIdent B_ID[max_broker_list_len];
|
||||
INT32 iSectorIndex;
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
// Select the range of brokers, honoring partitioning by CID settings.
|
||||
// iBrokersStart = iStartingBrokerID;
|
||||
// iBrokersCount = m_iActiveCustomerCount / iBrokersDiv;
|
||||
iNumBrokers = m_rnd.RndIntRange(min_broker_list_len,
|
||||
max_broker_list_len); // 20..40 brokers
|
||||
// Small databases (<=4LUs) may contain less than the chosen number of
|
||||
// brokers. Broker names for Broker Volume are unique, so need to re-adjust
|
||||
// or be caught in an infinite loop below.
|
||||
if (iNumBrokers > m_Brokers.GetBrokerCount()) {
|
||||
iNumBrokers = (INT32)m_Brokers.GetBrokerCount(); // adjust for small databases
|
||||
}
|
||||
|
||||
iCount = 0;
|
||||
do {
|
||||
// select random broker ID (from active customer range)
|
||||
B_ID[iCount] = m_Brokers.GenerateRandomBrokerId(&m_rnd);
|
||||
|
||||
for (i = 0; (i < iCount) && (B_ID[i] != B_ID[iCount]); ++i) {
|
||||
};
|
||||
|
||||
if (i == iCount) // make sure brokers are distinct
|
||||
{
|
||||
// put the broker name into the input parameter
|
||||
m_Brokers.GenerateBrokerName(B_ID[iCount], TxnReq.broker_list[iCount],
|
||||
static_cast<int>(sizeof(TxnReq.broker_list[iCount])));
|
||||
++iCount;
|
||||
}
|
||||
|
||||
} while (iCount < iNumBrokers);
|
||||
|
||||
// select sector name
|
||||
iSectorIndex = m_rnd.RndIntRange(0, m_iSectorCount - 1);
|
||||
|
||||
strncpy(TxnReq.sector_name, m_pSectors[iSectorIndex].SC_NAME_CSTR(), sizeof(TxnReq.sector_name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Customer-Position transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateCustomerPositionInput(TCustomerPositionTxnInput &TxnReq) {
|
||||
TIdent iCustomerId;
|
||||
eCustomerTier iCustomerTier;
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
GenerateNonUniformRandomCustomerId(iCustomerId, iCustomerTier);
|
||||
|
||||
if (m_rnd.RndPercent(m_pDriverCETxnSettings->CP_settings.cur.by_tax_id)) {
|
||||
// send tax id instead of customer id
|
||||
m_Person.GetTaxID(iCustomerId, TxnReq.tax_id);
|
||||
} else {
|
||||
// send customer id and not the tax id
|
||||
TxnReq.cust_id = iCustomerId;
|
||||
}
|
||||
|
||||
TxnReq.get_history = m_rnd.RndPercent(m_pDriverCETxnSettings->CP_settings.cur.get_history);
|
||||
if (TxnReq.get_history) {
|
||||
TxnReq.acct_id_idx = m_rnd.RndIntRange(0, m_AccsAndPerms.GetNumberOfAccounts(iCustomerId, iCustomerTier) - 1);
|
||||
} else {
|
||||
TxnReq.acct_id_idx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Market-Watch transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateMarketWatchInput(TMarketWatchTxnInput &TxnReq) {
|
||||
TIdent iCustomerId;
|
||||
eCustomerTier iCustomerTier;
|
||||
INT32 iThreshold;
|
||||
INT32 iWeek;
|
||||
INT32 iDailyMarketDay;
|
||||
CDateTime StartDate(iDailyMarketBaseYear, iDailyMarketBaseMonth, iDailyMarketBaseDay, iDailyMarketBaseHour,
|
||||
iDailyMarketBaseMinute, iDailyMarketBaseSecond, iDailyMarketBaseMsec);
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
|
||||
// have some distribution on what inputs to send
|
||||
if (iThreshold <= m_pDriverCETxnSettings->MW_settings.cur.by_industry) {
|
||||
// send industry name
|
||||
strncpy(TxnReq.industry_name, m_pIndustries[m_rnd.RndIntRange(0, m_iIndustryCount - 1)].IN_NAME_CSTR(),
|
||||
sizeof(TxnReq.industry_name));
|
||||
|
||||
if (iBaseCompanyCount < m_iActiveCompanyCount) {
|
||||
TxnReq.starting_co_id = m_rnd.RndInt64Range(
|
||||
m_iStartFromCompany, m_iStartFromCompany + m_iActiveCompanyCount - (iBaseCompanyCount - 1));
|
||||
TxnReq.ending_co_id = TxnReq.starting_co_id + (iBaseCompanyCount - 1);
|
||||
} else {
|
||||
TxnReq.starting_co_id = m_iStartFromCompany;
|
||||
TxnReq.ending_co_id = m_iStartFromCompany + m_iActiveCompanyCount - 1;
|
||||
}
|
||||
} else {
|
||||
if (iThreshold <= (m_pDriverCETxnSettings->MW_settings.cur.by_industry +
|
||||
m_pDriverCETxnSettings->MW_settings.cur.by_watch_list)) {
|
||||
// Send customer id
|
||||
GenerateNonUniformRandomCustomerId(TxnReq.c_id, iCustomerTier);
|
||||
} else {
|
||||
// Send account id
|
||||
GenerateNonUniformRandomCustomerId(iCustomerId, iCustomerTier);
|
||||
m_AccsAndPerms.GenerateRandomAccountId(m_rnd, iCustomerId, iCustomerTier, &TxnReq.acct_id, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Set start_day for both cases of the 'if'.
|
||||
//
|
||||
iWeek = (INT32)m_rnd.NURnd(0, 255, 255, 0) + 5; // A = 255, S = 0
|
||||
// Week is now between 5 and 260.
|
||||
// Select a day within the week.
|
||||
//
|
||||
iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
if (iThreshold > 40) {
|
||||
iDailyMarketDay = iWeek * DaysPerWeek + 4; // Friday
|
||||
} else // 1..40 case
|
||||
{
|
||||
if (iThreshold <= 20) {
|
||||
iDailyMarketDay = iWeek * DaysPerWeek; // Monday
|
||||
} else {
|
||||
if (iThreshold <= 27) {
|
||||
iDailyMarketDay = iWeek * DaysPerWeek + 1; // Tuesday
|
||||
} else {
|
||||
if (iThreshold <= 33) {
|
||||
iDailyMarketDay = iWeek * DaysPerWeek + 2; // Wednesday
|
||||
} else {
|
||||
iDailyMarketDay = iWeek * DaysPerWeek + 3; // Thursday
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go back 256 weeks and then add our calculated day.
|
||||
//
|
||||
StartDate.Add(iDailyMarketDay, 0);
|
||||
|
||||
StartDate.GetTimeStamp(&TxnReq.start_day);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Security-Detail transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateSecurityDetailInput(TSecurityDetailTxnInput &TxnReq) {
|
||||
CDateTime StartDate(iDailyMarketBaseYear, iDailyMarketBaseMonth, iDailyMarketBaseDay, iDailyMarketBaseHour,
|
||||
iDailyMarketBaseMinute, iDailyMarketBaseSecond, iDailyMarketBaseMsec);
|
||||
INT32 iStartDay; // day from the StartDate
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
// random symbol
|
||||
m_pSecurities.CreateSymbol(m_rnd.RndInt64Range(0, m_iActiveSecurityCount - 1), TxnReq.symbol,
|
||||
static_cast<int>(sizeof(TxnReq.symbol)));
|
||||
|
||||
// Whether or not to access the LOB.
|
||||
TxnReq.access_lob_flag = m_rnd.RndPercent(m_pDriverCETxnSettings->SD_settings.cur.LOBAccessPercentage);
|
||||
|
||||
// random number of financial rows to return
|
||||
TxnReq.max_rows_to_return = m_rnd.RndIntRange(iSecurityDetailMinRows, iSecurityDetailMaxRows);
|
||||
|
||||
iStartDay = m_rnd.RndIntRange(0, iDailyMarketTotalRows - TxnReq.max_rows_to_return);
|
||||
|
||||
// add the offset
|
||||
StartDate.Add(iStartDay, 0);
|
||||
|
||||
StartDate.GetTimeStamp(&TxnReq.start_day);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Trade-Lookup transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateTradeLookupInput(TTradeLookupTxnInput &TxnReq) {
|
||||
INT32 iThreshold;
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
|
||||
if (iThreshold <= m_pDriverCETxnSettings->TL_settings.cur.do_frame1) {
|
||||
// Frame 1
|
||||
TxnReq.frame_to_execute = 1;
|
||||
TxnReq.max_trades = m_pDriverCETxnSettings->TL_settings.cur.MaxRowsFrame1;
|
||||
|
||||
// Generate list of unique trade id's
|
||||
int ii, jj;
|
||||
bool Accepted;
|
||||
TTrade TID;
|
||||
|
||||
for (ii = 0; ii < TxnReq.max_trades; ii++) {
|
||||
Accepted = false;
|
||||
while (!Accepted) {
|
||||
TID = GenerateNonUniformTradeID(TradeLookupAValueForTradeIDGenFrame1,
|
||||
TradeLookupSValueForTradeIDGenFrame1);
|
||||
jj = 0;
|
||||
while (jj < ii && TxnReq.trade_id[jj] != TID) {
|
||||
jj++;
|
||||
}
|
||||
if (jj == ii) {
|
||||
// We have a unique TID for this batch
|
||||
TxnReq.trade_id[ii] = TID;
|
||||
Accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (iThreshold <=
|
||||
m_pDriverCETxnSettings->TL_settings.cur.do_frame1 + m_pDriverCETxnSettings->TL_settings.cur.do_frame2) {
|
||||
// Frame 2
|
||||
TxnReq.frame_to_execute = 2;
|
||||
TxnReq.acct_id = GenerateRandomCustomerAccountId();
|
||||
TxnReq.max_trades = m_pDriverCETxnSettings->TL_settings.cur.MaxRowsFrame2;
|
||||
|
||||
GenerateNonUniformTradeDTS(TxnReq.start_trade_dts, m_iTradeLookupFrame2MaxTimeInMilliSeconds,
|
||||
TradeLookupAValueForTimeGenFrame2, TradeLookupSValueForTimeGenFrame2);
|
||||
|
||||
// Set to the end of initial trades.
|
||||
m_EndTime.GetTimeStamp(&TxnReq.end_trade_dts);
|
||||
} else if (iThreshold <= m_pDriverCETxnSettings->TL_settings.cur.do_frame1 +
|
||||
m_pDriverCETxnSettings->TL_settings.cur.do_frame2 +
|
||||
m_pDriverCETxnSettings->TL_settings.cur.do_frame3) {
|
||||
// Frame 3
|
||||
TxnReq.frame_to_execute = 3;
|
||||
TxnReq.max_trades = m_pDriverCETxnSettings->TL_settings.cur.MaxRowsFrame3;
|
||||
|
||||
m_pSecurities.CreateSymbol(m_rnd.NURnd(0, m_iActiveSecurityCount - 1, TradeLookupAValueForSymbolFrame3,
|
||||
TradeLookupSValueForSymbolFrame3),
|
||||
TxnReq.symbol, static_cast<int>(sizeof(TxnReq.symbol)));
|
||||
|
||||
GenerateNonUniformTradeDTS(TxnReq.start_trade_dts, m_iTradeLookupFrame3MaxTimeInMilliSeconds,
|
||||
TradeLookupAValueForTimeGenFrame3, TradeLookupSValueForTimeGenFrame3);
|
||||
|
||||
// Set to the end of initial trades.
|
||||
m_EndTime.GetTimeStamp(&TxnReq.end_trade_dts);
|
||||
|
||||
TxnReq.max_acct_id = m_AccsAndPerms.GetEndingCA_ID(m_iActiveCustomerCount);
|
||||
} else {
|
||||
// Frame 4
|
||||
TxnReq.frame_to_execute = 4;
|
||||
TxnReq.acct_id = GenerateRandomCustomerAccountId();
|
||||
GenerateNonUniformTradeDTS(TxnReq.start_trade_dts, m_iTradeLookupFrame4MaxTimeInMilliSeconds,
|
||||
TradeLookupAValueForTimeGenFrame4, TradeLookupSValueForTimeGenFrame4);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Trade-Order transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction. OUT TradeType - integer representation of
|
||||
* generated trade type (as eTradeTypeID enum). OUT bExecutorIsAccountOwner -
|
||||
* whether Trade-Order frame 2 should (FALSE) or shouldn't (TRUE) be called.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateTradeOrderInput(TTradeOrderTxnInput &TxnReq, INT32 &iTradeType,
|
||||
bool &bExecutorIsAccountOwner) {
|
||||
TIdent iCustomerId; // owner
|
||||
eCustomerTier iCustomerTier;
|
||||
TIdent CID_1, CID_2;
|
||||
bool bMarket;
|
||||
INT32 iAdditionalPerms;
|
||||
UINT iSymbIndex;
|
||||
TIdent iFlatFileSymbIndex;
|
||||
eTradeTypeID eTradeType;
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
// Generate random customer
|
||||
//
|
||||
GenerateNonUniformRandomCustomerId(iCustomerId, iCustomerTier);
|
||||
|
||||
// Generate random account id and security index
|
||||
//
|
||||
m_Holdings.GenerateRandomAccountSecurity(iCustomerId, iCustomerTier, &TxnReq.acct_id, &iFlatFileSymbIndex,
|
||||
&iSymbIndex);
|
||||
|
||||
// find out how many permission rows there are for this account (in addition
|
||||
// to the owner's)
|
||||
iAdditionalPerms = m_AccsAndPerms.GetNumPermsForCA(TxnReq.acct_id);
|
||||
// distribution same as in the loader for now
|
||||
if (iAdditionalPerms == 0) { // select the owner
|
||||
m_Person.GetFirstLastAndTaxID(iCustomerId, TxnReq.exec_f_name, TxnReq.exec_l_name, TxnReq.exec_tax_id);
|
||||
|
||||
bExecutorIsAccountOwner = true;
|
||||
} else {
|
||||
// If there is more than one permission set on the account,
|
||||
// have some distribution on whether the executor is still
|
||||
// the account owner, or it is one of the additional permissions.
|
||||
// Here we must take into account the fact that we've excluded
|
||||
// a large portion of customers that don't have any additional
|
||||
// executors in the above code (iAdditionalPerms == 0); the
|
||||
// "exec_is_owner" percentage implicity includes such customers
|
||||
// and must be factored out here.
|
||||
|
||||
int exec_is_owner =
|
||||
(m_pDriverCETxnSettings->TO_settings.cur.exec_is_owner - iPercentAccountAdditionalPermissions_0) * 100 /
|
||||
(100 - iPercentAccountAdditionalPermissions_0);
|
||||
|
||||
if (m_rnd.RndPercent(exec_is_owner)) {
|
||||
m_Person.GetFirstLastAndTaxID(iCustomerId, TxnReq.exec_f_name, TxnReq.exec_l_name, TxnReq.exec_tax_id);
|
||||
|
||||
bExecutorIsAccountOwner = true;
|
||||
} else {
|
||||
if (iAdditionalPerms == 1) {
|
||||
// select the first non-owner
|
||||
m_AccsAndPerms.GetCIDsForPermissions(TxnReq.acct_id, iCustomerId, &CID_1, NULL);
|
||||
|
||||
m_Person.GetFirstLastAndTaxID(CID_1, TxnReq.exec_f_name, TxnReq.exec_l_name, TxnReq.exec_tax_id);
|
||||
} else {
|
||||
// select the second non-owner
|
||||
m_AccsAndPerms.GetCIDsForPermissions(TxnReq.acct_id, iCustomerId, &CID_1, &CID_2);
|
||||
// generate third account permission row
|
||||
m_Person.GetFirstLastAndTaxID(CID_2, TxnReq.exec_f_name, TxnReq.exec_l_name, TxnReq.exec_tax_id);
|
||||
}
|
||||
|
||||
bExecutorIsAccountOwner = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Select either stock symbol or company from the securities flat file.
|
||||
//
|
||||
|
||||
// have some distribution on the company/symbol input preference
|
||||
if (m_rnd.RndPercent(m_pDriverCETxnSettings->TO_settings.cur.security_by_symbol)) {
|
||||
// Submit the symbol
|
||||
m_pSecurities.CreateSymbol(iFlatFileSymbIndex, TxnReq.symbol, static_cast<int>(sizeof(TxnReq.symbol)));
|
||||
} else {
|
||||
// Submit the company name
|
||||
m_pCompanies.CreateName(m_pSecurities.GetCompanyIndex(iFlatFileSymbIndex), TxnReq.co_name,
|
||||
static_cast<int>(sizeof(TxnReq.co_name)));
|
||||
|
||||
strncpy(TxnReq.issue, m_pSecurities.GetRecord(iFlatFileSymbIndex).S_ISSUE_CSTR(), sizeof(TxnReq.issue));
|
||||
}
|
||||
|
||||
TxnReq.trade_qty = cTRADE_QTY_SIZES[m_rnd.RndIntRange(0, cNUM_TRADE_QTY_SIZES - 1)];
|
||||
TxnReq.requested_price = m_rnd.RndDoubleIncrRange(fMinSecPrice, fMaxSecPrice, 0.01);
|
||||
|
||||
// Determine whether Market or Limit order
|
||||
bMarket = m_rnd.RndPercent(m_pDriverCETxnSettings->TO_settings.cur.market);
|
||||
|
||||
// Determine whether Buy or Sell trade
|
||||
if (m_rnd.RndPercent(m_pDriverCETxnSettings->TO_settings.cur.buy_orders)) {
|
||||
if (bMarket) {
|
||||
// Market Buy
|
||||
eTradeType = eMarketBuy;
|
||||
} else {
|
||||
// Limit Buy
|
||||
eTradeType = eLimitBuy;
|
||||
}
|
||||
|
||||
// Set margin or cash for Buy
|
||||
TxnReq.type_is_margin = m_rnd.RndPercent(
|
||||
// type_is_margin is specified for all orders, but used only for
|
||||
// buys
|
||||
m_pDriverCETxnSettings->TO_settings.cur.type_is_margin * 100 /
|
||||
m_pDriverCETxnSettings->TO_settings.cur.buy_orders);
|
||||
} else {
|
||||
if (bMarket) {
|
||||
// Market Sell
|
||||
eTradeType = eMarketSell;
|
||||
} else {
|
||||
// determine whether the Limit Sell is a Stop Loss
|
||||
if (m_rnd.RndPercent(m_pDriverCETxnSettings->TO_settings.cur.stop_loss)) {
|
||||
// Stop Loss
|
||||
eTradeType = eStopLoss;
|
||||
} else {
|
||||
// Limit Sell
|
||||
eTradeType = eLimitSell;
|
||||
}
|
||||
}
|
||||
|
||||
TxnReq.type_is_margin = false; // all sell orders are cash
|
||||
}
|
||||
iTradeType = eTradeType;
|
||||
|
||||
// Distribution of last-in-first-out flag
|
||||
TxnReq.is_lifo = m_rnd.RndPercent(m_pDriverCETxnSettings->TO_settings.cur.lifo);
|
||||
|
||||
// Copy the trade type id from the flat file
|
||||
strncpy(TxnReq.trade_type_id, m_pTradeType[eTradeType].TT_ID_CSTR(), sizeof(TxnReq.trade_type_id));
|
||||
|
||||
// Copy the status type id's from the flat file
|
||||
strncpy(TxnReq.st_pending_id, m_pStatusType[ePending].ST_ID_CSTR(), sizeof(TxnReq.st_pending_id));
|
||||
strncpy(TxnReq.st_submitted_id, m_pStatusType[eSubmitted].ST_ID_CSTR(), sizeof(TxnReq.st_submitted_id));
|
||||
|
||||
TxnReq.roll_it_back = (m_iTradeOrderRollbackLevel >= m_rnd.RndIntRange(1, m_iTradeOrderRollbackLimit));
|
||||
|
||||
// Need to address logging more comprehensively.
|
||||
// return eTradeType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Trade-Status transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateTradeStatusInput(TTradeStatusTxnInput &TxnReq) {
|
||||
TIdent iCustomerId;
|
||||
eCustomerTier iCustomerTier;
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
// select customer id first
|
||||
GenerateNonUniformRandomCustomerId(iCustomerId, iCustomerTier);
|
||||
|
||||
// select random account id
|
||||
m_AccsAndPerms.GenerateRandomAccountId(m_rnd, iCustomerId, iCustomerTier, &TxnReq.acct_id, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Trade-Update transaction input.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* OUT TxnReq - input parameter structure filled in
|
||||
* for the transaction.
|
||||
*
|
||||
* RETURNS:
|
||||
* none.
|
||||
*/
|
||||
void CCETxnInputGenerator::GenerateTradeUpdateInput(TTradeUpdateTxnInput &TxnReq) {
|
||||
INT32 iThreshold;
|
||||
|
||||
// Make sure we're starting with a clean object.
|
||||
TxnReq.Clear();
|
||||
|
||||
iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
|
||||
if (iThreshold <= m_pDriverCETxnSettings->TU_settings.cur.do_frame1) {
|
||||
// Frame 1
|
||||
TxnReq.frame_to_execute = 1;
|
||||
TxnReq.max_trades = m_pDriverCETxnSettings->TU_settings.cur.MaxRowsFrame1;
|
||||
TxnReq.max_updates = m_pDriverCETxnSettings->TU_settings.cur.MaxRowsToUpdateFrame1;
|
||||
|
||||
// Generate list of unique trade id's
|
||||
int ii, jj;
|
||||
bool Accepted;
|
||||
TTrade TID;
|
||||
|
||||
for (ii = 0; ii < TxnReq.max_trades; ii++) {
|
||||
Accepted = false;
|
||||
while (!Accepted) {
|
||||
TID = GenerateNonUniformTradeID(TradeUpdateAValueForTradeIDGenFrame1,
|
||||
TradeUpdateSValueForTradeIDGenFrame1);
|
||||
jj = 0;
|
||||
while (jj < ii && TxnReq.trade_id[jj] != TID) {
|
||||
jj++;
|
||||
}
|
||||
if (jj == ii) {
|
||||
// We have a unique TID for this batch
|
||||
TxnReq.trade_id[ii] = TID;
|
||||
Accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (iThreshold <=
|
||||
m_pDriverCETxnSettings->TU_settings.cur.do_frame1 + m_pDriverCETxnSettings->TU_settings.cur.do_frame2) {
|
||||
// Frame 2
|
||||
TxnReq.frame_to_execute = 2;
|
||||
TxnReq.max_trades = m_pDriverCETxnSettings->TU_settings.cur.MaxRowsFrame2;
|
||||
TxnReq.max_updates = m_pDriverCETxnSettings->TU_settings.cur.MaxRowsToUpdateFrame2;
|
||||
TxnReq.acct_id = GenerateRandomCustomerAccountId();
|
||||
|
||||
GenerateNonUniformTradeDTS(TxnReq.start_trade_dts, m_iTradeUpdateFrame2MaxTimeInMilliSeconds,
|
||||
TradeUpdateAValueForTimeGenFrame2, TradeUpdateSValueForTimeGenFrame2);
|
||||
|
||||
// Set to the end of initial trades.
|
||||
m_EndTime.GetTimeStamp(&TxnReq.end_trade_dts);
|
||||
} else {
|
||||
// Frame 3
|
||||
TxnReq.frame_to_execute = 3;
|
||||
TxnReq.max_trades = m_pDriverCETxnSettings->TU_settings.cur.MaxRowsFrame3;
|
||||
TxnReq.max_updates = m_pDriverCETxnSettings->TU_settings.cur.MaxRowsToUpdateFrame3;
|
||||
|
||||
m_pSecurities.CreateSymbol(m_rnd.NURnd(0, m_iActiveSecurityCount - 1, TradeUpdateAValueForSymbolFrame3,
|
||||
TradeUpdateSValueForSymbolFrame3),
|
||||
TxnReq.symbol, static_cast<int>(sizeof(TxnReq.symbol)));
|
||||
|
||||
GenerateNonUniformTradeDTS(TxnReq.start_trade_dts, m_iTradeUpdateFrame3MaxTimeInMilliSeconds,
|
||||
TradeUpdateAValueForTimeGenFrame3, TradeUpdateSValueForTimeGenFrame3);
|
||||
|
||||
// Set to the end of initial trades.
|
||||
m_EndTime.GetTimeStamp(&TxnReq.end_trade_dts);
|
||||
|
||||
TxnReq.max_acct_id = m_AccsAndPerms.GetEndingCA_ID(m_iActiveCustomerCount);
|
||||
}
|
||||
}
|
||||
179
external/duckdb/third_party/tpce-tool/main/CETxnMixGenerator.cpp
vendored
Normal file
179
external/duckdb/third_party/tpce-tool/main/CETxnMixGenerator.cpp
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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
|
||||
* - Gregory Dake, Cecil Reames, Doug Johnson, Matt Emmerton
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of CTxnGeneration class.
|
||||
* See TxnMixGenerator.h for description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/CETxnMixGenerator.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CCETxnMixGenerator::CCETxnMixGenerator(const PDriverCETxnSettings pDriverCETxnSettings, CBaseLogger *pLogger)
|
||||
: m_pDriverCETxnSettings(pDriverCETxnSettings), m_rnd(RNGSeedBaseTxnMixGenerator) // initialize with default seed
|
||||
,
|
||||
m_pLogger(pLogger), m_iTxnArrayCurrentIndex(0), m_pTxnArray(NULL) {
|
||||
// UpdateTunables() is called from CCE constructor (Initialize)
|
||||
}
|
||||
|
||||
CCETxnMixGenerator::CCETxnMixGenerator(const PDriverCETxnSettings pDriverCETxnSettings, RNGSEED RNGSeed,
|
||||
CBaseLogger *pLogger)
|
||||
: m_pDriverCETxnSettings(pDriverCETxnSettings), m_rnd(RNGSeed) // seed is provided for us
|
||||
,
|
||||
m_pLogger(pLogger), m_iTxnArrayCurrentIndex(0), m_pTxnArray(NULL) {
|
||||
// UpdateTunables() is called from CCE constructor (Initialize)
|
||||
}
|
||||
|
||||
RNGSEED CCETxnMixGenerator::GetRNGSeed(void) {
|
||||
return (m_rnd.GetSeed());
|
||||
}
|
||||
|
||||
void CCETxnMixGenerator::SetRNGSeed(RNGSEED RNGSeed) {
|
||||
m_rnd.SetSeed(RNGSeed);
|
||||
}
|
||||
|
||||
CCETxnMixGenerator::~CCETxnMixGenerator() {
|
||||
if (m_pTxnArray != NULL) {
|
||||
delete[] m_pTxnArray;
|
||||
m_pTxnArray = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CCETxnMixGenerator::UpdateTunables(void) {
|
||||
INT32 i;
|
||||
INT32 BrokerVolumeMixLimit;
|
||||
INT32 CustomerPositionMixLimit;
|
||||
INT32 MarketWatchMixLimit;
|
||||
INT32 SecurityDetailMixLimit;
|
||||
INT32 TradeLookupMixLimit;
|
||||
INT32 TradeOrderMixLimit;
|
||||
INT32 TradeStatusMixLimit;
|
||||
INT32 TradeUpdateMixLimit;
|
||||
|
||||
// Add all the weights together
|
||||
m_CETransactionMixTotal = m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.BrokerVolumeMixLevel +
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.CustomerPositionMixLevel +
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.MarketWatchMixLevel +
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.SecurityDetailMixLevel +
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeLookupMixLevel +
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeOrderMixLevel +
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeStatusMixLevel +
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeUpdateMixLevel;
|
||||
|
||||
TradeStatusMixLimit = m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeStatusMixLevel;
|
||||
MarketWatchMixLimit =
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.MarketWatchMixLevel + TradeStatusMixLimit;
|
||||
SecurityDetailMixLimit =
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.SecurityDetailMixLevel + MarketWatchMixLimit;
|
||||
CustomerPositionMixLimit =
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.CustomerPositionMixLevel + SecurityDetailMixLimit;
|
||||
TradeOrderMixLimit =
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeOrderMixLevel + CustomerPositionMixLimit;
|
||||
TradeLookupMixLimit = m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeLookupMixLevel + TradeOrderMixLimit;
|
||||
TradeUpdateMixLimit =
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeUpdateMixLevel + TradeLookupMixLimit;
|
||||
BrokerVolumeMixLimit =
|
||||
m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.BrokerVolumeMixLevel + TradeUpdateMixLimit;
|
||||
|
||||
// Reset the random transaction array.
|
||||
//
|
||||
if (m_pTxnArray != NULL) {
|
||||
delete[] m_pTxnArray;
|
||||
m_pTxnArray = NULL;
|
||||
}
|
||||
|
||||
m_pTxnArray = new char[m_CETransactionMixTotal];
|
||||
|
||||
// Initialize the array with transaction types.
|
||||
//
|
||||
for (i = 0; i < TradeStatusMixLimit; ++i) {
|
||||
m_pTxnArray[i] = TRADE_STATUS;
|
||||
}
|
||||
for (; i < MarketWatchMixLimit; ++i) {
|
||||
m_pTxnArray[i] = MARKET_WATCH;
|
||||
}
|
||||
for (; i < SecurityDetailMixLimit; ++i) {
|
||||
m_pTxnArray[i] = SECURITY_DETAIL;
|
||||
}
|
||||
for (; i < CustomerPositionMixLimit; ++i) {
|
||||
m_pTxnArray[i] = CUSTOMER_POSITION;
|
||||
}
|
||||
for (; i < TradeOrderMixLimit; ++i) {
|
||||
m_pTxnArray[i] = TRADE_ORDER;
|
||||
}
|
||||
for (; i < TradeLookupMixLimit; ++i) {
|
||||
m_pTxnArray[i] = TRADE_LOOKUP;
|
||||
}
|
||||
for (; i < TradeUpdateMixLimit; ++i) {
|
||||
m_pTxnArray[i] = TRADE_UPDATE;
|
||||
}
|
||||
for (; i < BrokerVolumeMixLimit; ++i) {
|
||||
m_pTxnArray[i] = BROKER_VOLUME;
|
||||
}
|
||||
|
||||
m_iTxnArrayCurrentIndex = 0; // reset the current element index
|
||||
|
||||
// Log Tunables
|
||||
m_pLogger->SendToLogger(m_pDriverCETxnSettings->TxnMixGenerator_settings);
|
||||
}
|
||||
|
||||
int CCETxnMixGenerator::GenerateNextTxnType() {
|
||||
// Select the next transaction type using the "card deck shuffle"
|
||||
// algorithm (also Knuth algorithm) that guarantees a certain number
|
||||
// of transactions of each type is returned.
|
||||
//
|
||||
// 1) Get a 32-bit random number.
|
||||
// 2) Use random number to select next transaction type from m_pTxnArray
|
||||
// in the range [m_iTxnArrayCurrentIndex, m_CETransactionMixTotal).
|
||||
// 3) Swap the selected random element in m_pTxnArray
|
||||
// with m_pTxnArray[m_iTxnArrayCurrentIndex].
|
||||
// 4) Increment m_iTxnArrayCurrentIndex to remove the returned
|
||||
// transaction type from further consideration.
|
||||
//
|
||||
INT32 rnd = m_rnd.RndIntRange(m_iTxnArrayCurrentIndex, m_CETransactionMixTotal - 1);
|
||||
|
||||
char iTxnType = m_pTxnArray[rnd];
|
||||
|
||||
// Swap two array entries.
|
||||
//
|
||||
m_pTxnArray[rnd] = m_pTxnArray[m_iTxnArrayCurrentIndex];
|
||||
m_pTxnArray[m_iTxnArrayCurrentIndex] = iTxnType;
|
||||
|
||||
m_iTxnArrayCurrentIndex = (m_iTxnArrayCurrentIndex + 1) % m_CETransactionMixTotal;
|
||||
|
||||
return iTxnType;
|
||||
}
|
||||
38
external/duckdb/third_party/tpce-tool/main/CMakeLists.txt
vendored
Normal file
38
external/duckdb/third_party/tpce-tool/main/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
add_library(tpce_main OBJECT
|
||||
AddressTable.cpp
|
||||
BaseLogger.cpp
|
||||
CE.cpp
|
||||
CETxnInputGenerator.cpp
|
||||
CETxnMixGenerator.cpp
|
||||
ChargeTable.cpp
|
||||
CommissionRateTable.cpp
|
||||
CustomerSelection.cpp
|
||||
CustomerTable.cpp
|
||||
DM.cpp
|
||||
EGenGenerateAndLoad.cpp
|
||||
EGenLogFormatterTab.cpp
|
||||
ExchangeTable.cpp
|
||||
FlatFileLoader.cpp
|
||||
IndustryTable.cpp
|
||||
MEE.cpp
|
||||
MEEPriceBoard.cpp
|
||||
MEESecurity.cpp
|
||||
MEETickerTape.cpp
|
||||
MEETradingFloor.cpp
|
||||
Person.cpp
|
||||
SectorTable.cpp
|
||||
StatusTypeTable.cpp
|
||||
TaxRateTable.cpp
|
||||
TradeGen.cpp
|
||||
TradeTypeTable.cpp
|
||||
WheelTime.cpp
|
||||
ZipCodeTable.cpp
|
||||
bucketsimulator.cpp
|
||||
progressmeter.cpp
|
||||
progressmeterinterface.cpp
|
||||
strutil.cpp)
|
||||
set(TPCE_OBJECT_FILES
|
||||
${TPCE_OBJECT_FILES} $<TARGET_OBJECTS:tpce_main>
|
||||
PARENT_SCOPE)
|
||||
|
||||
disable_target_warnings(tpce_main)
|
||||
55
external/duckdb/third_party/tpce-tool/main/ChargeTable.cpp
vendored
Normal file
55
external/duckdb/third_party/tpce-tool/main/ChargeTable.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/ChargeTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CChargeTable::CChargeTable(const ChargeDataFile_t &dataFile) : FixedTable<ChargeDataFile_t, CHARGE_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
CChargeTable::~CChargeTable() {
|
||||
}
|
||||
|
||||
void CChargeTable::LoadTableRow() {
|
||||
const ChargeDataFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
tableRow.CH_CHRG = dataRecord.CH_CHRG();
|
||||
tableRow.CH_C_TIER = dataRecord.CH_C_TIER();
|
||||
strncpy(tableRow.CH_TT_ID, dataRecord.CH_TT_ID_CSTR(), sizeof(tableRow.CH_TT_ID));
|
||||
}
|
||||
59
external/duckdb/third_party/tpce-tool/main/CommissionRateTable.cpp
vendored
Normal file
59
external/duckdb/third_party/tpce-tool/main/CommissionRateTable.cpp
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/CommissionRateTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CCommissionRateTable::CCommissionRateTable(const CommissionRateDataFile_t &dataFile)
|
||||
: FixedTable<CommissionRateDataFile_t, COMMISSION_RATE_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
CCommissionRateTable::~CCommissionRateTable() {
|
||||
}
|
||||
|
||||
void CCommissionRateTable::LoadTableRow() {
|
||||
const CommissionRateDataFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
tableRow.CR_C_TIER = dataRecord.CR_C_TIER();
|
||||
strncpy(tableRow.CR_EX_ID, dataRecord.CR_EX_ID_CSTR(), sizeof(tableRow.CR_EX_ID));
|
||||
tableRow.CR_FROM_QTY = dataRecord.CR_FROM_QTY();
|
||||
tableRow.CR_RATE = dataRecord.CR_RATE();
|
||||
tableRow.CR_TO_QTY = dataRecord.CR_TO_QTY();
|
||||
strncpy(tableRow.CR_TT_ID, dataRecord.CR_TT_ID_CSTR(), sizeof(tableRow.CR_TT_ID));
|
||||
}
|
||||
273
external/duckdb/third_party/tpce-tool/main/CustomerSelection.cpp
vendored
Normal file
273
external/duckdb/third_party/tpce-tool/main/CustomerSelection.cpp
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 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
|
||||
* - Sergey Vasilevskiy, Doug Johnson
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of the CustomerSelection class.
|
||||
* (see CustomerSelction.h for details)
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/EGenTables_stdafx.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
/*
|
||||
* Default constructor.
|
||||
*/
|
||||
CCustomerSelection::CCustomerSelection()
|
||||
: m_pRND(NULL), m_iStartFromCustomer(0 + iTIdentShift), m_iCustomerCount(0), m_bPartitionByCID(false),
|
||||
m_iPartitionPercent(0), m_iMyStartFromCustomer(0 + iTIdentShift), m_iMyCustomerCount(0) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor to set the customer range when not partitioining
|
||||
*/
|
||||
CCustomerSelection::CCustomerSelection(CRandom *pRND, TIdent iStartFromCustomer, TIdent iCustomerCount)
|
||||
: m_pRND(pRND), m_iStartFromCustomer(iStartFromCustomer + iTIdentShift), m_iCustomerCount(iCustomerCount),
|
||||
m_bPartitionByCID(false), m_iPartitionPercent(0), m_iMyStartFromCustomer(0 + iTIdentShift),
|
||||
m_iMyCustomerCount(0) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor to set subrange when partitioning by C_ID.
|
||||
*/
|
||||
CCustomerSelection::CCustomerSelection(CRandom *pRND, TIdent iStartFromCustomer, TIdent iCustomerCount,
|
||||
int iPartitionPercent, TIdent iMyStartFromCustomer, TIdent iMyCustomerCount)
|
||||
: m_pRND(pRND), m_iStartFromCustomer(iStartFromCustomer + iTIdentShift), m_iCustomerCount(iCustomerCount)
|
||||
|
||||
,
|
||||
m_bPartitionByCID(true), m_iPartitionPercent(iPartitionPercent),
|
||||
m_iMyStartFromCustomer(iMyStartFromCustomer + iTIdentShift), m_iMyCustomerCount(iMyCustomerCount) {
|
||||
if ((iStartFromCustomer == iMyStartFromCustomer) && (iCustomerCount == iMyCustomerCount)) {
|
||||
// Even though the partitioning constructor was called, we're apparently
|
||||
// not really partitioning.
|
||||
m_bPartitionByCID = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-set the customer range for the partition.
|
||||
*/
|
||||
void CCustomerSelection::SetPartitionRange(TIdent iStartFromCustomer, TIdent iCustomerCount) {
|
||||
if (m_bPartitionByCID) {
|
||||
m_iMyStartFromCustomer = iStartFromCustomer;
|
||||
m_iMyCustomerCount = iCustomerCount;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Forward permutation.
|
||||
*/
|
||||
TIdent CCustomerSelection::Permute(TIdent iLow, TIdent iHigh) {
|
||||
return ((677 * iLow + 33 * (iHigh + 1)) % 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inverse permutation.
|
||||
*/
|
||||
TIdent CCustomerSelection::InversePermute(TIdent iLow, TIdent iHigh) {
|
||||
// Extra mod to make the result always positive
|
||||
//
|
||||
return (((((613 * (iLow - 33 * (iHigh + 1))) % 1000) + 1000) % 1000));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return scrambled inverse customer id in range of 0 to 999.
|
||||
*/
|
||||
UINT CCustomerSelection::GetInverseCID(TIdent C_ID) {
|
||||
UINT iCHigh = (UINT)CHigh(C_ID);
|
||||
UINT iInverseCID = (UINT)InversePermute(CLow(C_ID), iCHigh);
|
||||
|
||||
if (iInverseCID < 200) // Tier 1: value 0 to 199
|
||||
{
|
||||
return ((3 * iInverseCID + (iCHigh + 1)) % 200);
|
||||
} else {
|
||||
if (iInverseCID < 800) // Tier 2: value 200 to 799
|
||||
{
|
||||
return (((59 * iInverseCID + 47 * (iCHigh + 1)) % 600) + 200);
|
||||
} else // Tier 3: value 800 to 999
|
||||
{
|
||||
return (((23 * iInverseCID + 17 * (iCHigh + 1)) % 200) + 800);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return customer tier.
|
||||
*/
|
||||
eCustomerTier CCustomerSelection::GetTier(TIdent C_ID) {
|
||||
TIdent iRevC_ID = InversePermute(CLow(C_ID), CHigh(C_ID));
|
||||
|
||||
if (iRevC_ID < 200) {
|
||||
return eCustomerTierOne;
|
||||
} else {
|
||||
if (iRevC_ID < 800) {
|
||||
return eCustomerTierTwo;
|
||||
} else {
|
||||
return eCustomerTierThree;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a non-uniform random customer and the associated tier.
|
||||
*/
|
||||
void CCustomerSelection::GenerateRandomCustomer(TIdent &C_ID, eCustomerTier &C_TIER) {
|
||||
// Can't use this function if there is no external RNG.
|
||||
//
|
||||
if (m_pRND == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
double fCW = m_pRND->RndDoubleIncrRange(0.0001, 2000, 0.000000001);
|
||||
|
||||
// Uniformly select the higher portion of the C_ID.
|
||||
// Use "short-circuit" logic to avoid unnecessary call to RNG.
|
||||
TIdent iCHigh;
|
||||
if (m_bPartitionByCID && m_pRND->RndPercent(m_iPartitionPercent)) {
|
||||
// Generate a load unit inside the partition.
|
||||
iCHigh = (m_pRND->RndInt64Range(m_iMyStartFromCustomer,
|
||||
m_iMyStartFromCustomer + m_iMyCustomerCount - 1) -
|
||||
1) // minus 1 for the upper boundary case
|
||||
/ 1000;
|
||||
} else {
|
||||
// Generate a load unit across the entire range
|
||||
iCHigh = (m_pRND->RndInt64Range(m_iStartFromCustomer,
|
||||
m_iStartFromCustomer + m_iCustomerCount - 1) -
|
||||
1) // minus 1 for the upper boundary case
|
||||
/ 1000;
|
||||
}
|
||||
|
||||
// Non-uniformly select the lower portion of the C_ID.
|
||||
//
|
||||
int iCLow;
|
||||
|
||||
if (fCW <= 200) {
|
||||
// tier one
|
||||
//
|
||||
iCLow = (int)ceil(sqrt(22500 + 500 * fCW) - 151);
|
||||
|
||||
C_TIER = eCustomerTierOne;
|
||||
} else {
|
||||
if (fCW <= 1400) {
|
||||
// tier two
|
||||
//
|
||||
iCLow = (int)ceil(sqrt(290000 + 1000 * fCW) - 501);
|
||||
|
||||
C_TIER = eCustomerTierTwo;
|
||||
} else {
|
||||
// tier three
|
||||
//
|
||||
iCLow = (int)ceil(149 + sqrt(500 * fCW - 277500));
|
||||
|
||||
C_TIER = eCustomerTierThree;
|
||||
}
|
||||
}
|
||||
|
||||
C_ID = iCHigh * 1000 + Permute(iCLow, iCHigh) + 1;
|
||||
}
|
||||
|
||||
/////////*
|
||||
////////* Return a non-uniform random customer and tier.
|
||||
////////*/
|
||||
////////void CCustomerSelection::GenerateCustomerIdAndTier(TIdent &C_ID,
|
||||
/// eCustomerTier &C_TIER, bool bAcrossEntireRange)
|
||||
////////{
|
||||
//////// // Can't use this function if there is no external RNG.
|
||||
//////// //
|
||||
//////// if (m_pRND == NULL)
|
||||
//////// {
|
||||
//////// return;
|
||||
//////// }
|
||||
////////
|
||||
//////// double fCW = m_pRND->RndDoubleRange(0.0001, 2000);
|
||||
////////
|
||||
//////// // Select uniformly higher portion of the Customer ID.
|
||||
//////// //
|
||||
//////// TIdent iCHigh;
|
||||
//////// if (bAcrossEntireRange)
|
||||
//////// {
|
||||
//////// // Generate a load unit across the entire range
|
||||
//////// iCHigh = (m_pRND->RndInt64Range(1,
|
||||
/// m_iAdjustedTotalCustomerCount) - 1) // minus 1 for the upper boundary case
|
||||
//////// / 1000;
|
||||
//////// if( iCHigh >= ( m_iStartFromCustomer / 1000 ))
|
||||
//////// {
|
||||
//////// iCHigh += ( m_iCustomerCount / 1000 );
|
||||
//////// }
|
||||
//////// }
|
||||
//////// else
|
||||
//////// {
|
||||
//////// // Generate a load unit inside the parition.
|
||||
//////// iCHigh = (m_pRND->RndInt64Range(m_iStartFromCustomer,
|
||||
//////// m_iStartFromCustomer +
|
||||
/// m_iCustomerCount - 1) - 1) // minus 1 for the upper boundary case
|
||||
//////// / 1000;
|
||||
//////// }
|
||||
////////
|
||||
//////// // Select non-uniformly the lower portion of the Customer ID.
|
||||
//////// //
|
||||
//////// int iCLow;
|
||||
////////
|
||||
//////// if (fCW <= 200)
|
||||
//////// {
|
||||
//////// // tier one
|
||||
//////// //
|
||||
//////// iCLow = (int) ceil( sqrt(22500 + 500 * fCW) - 151 );
|
||||
////////
|
||||
//////// C_TIER = eCustomerTierOne;
|
||||
//////// }
|
||||
//////// else
|
||||
//////// {
|
||||
//////// if (fCW <=1400)
|
||||
//////// {
|
||||
//////// // tier two
|
||||
//////// //
|
||||
//////// iCLow = (int) ceil( sqrt(290000 + 1000 * fCW) - 501 );
|
||||
////////
|
||||
//////// C_TIER = eCustomerTierTwo;
|
||||
//////// }
|
||||
//////// else
|
||||
//////// {
|
||||
//////// // tier three
|
||||
//////// //
|
||||
//////// iCLow = (int) ceil( 149 + sqrt(500 * fCW - 277500) );
|
||||
////////
|
||||
//////// C_TIER = eCustomerTierThree;
|
||||
//////// }
|
||||
//////// }
|
||||
////////
|
||||
//////// C_ID = iCHigh * 1000 + Permute(iCLow, iCHigh) + 1;
|
||||
////////}
|
||||
411
external/duckdb/third_party/tpce-tool/main/CustomerTable.cpp
vendored
Normal file
411
external/duckdb/third_party/tpce-tool/main/CustomerTable.cpp
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* 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
|
||||
* - Sergey Vasilevskiy
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/EGenTables_stdafx.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
namespace TPCE {
|
||||
const char *szUSAreaCode = "011"; // USA/Canada phone area code
|
||||
char EMAIL_DOMAINs[iNumEMAIL_DOMAINs][15] = {"@msn.com", "@hotmail.com", "@rr.com",
|
||||
"@netzero.com", "@earthlink.com", "@attbi.com"};
|
||||
} // namespace TPCE
|
||||
|
||||
// Percentages used when generating C_TIER
|
||||
const int iPercentCustomersInC_TIER_1 = 20;
|
||||
const int iPercentCustomersInC_TIER_2 = 60;
|
||||
const int iPercentCustomersInC_TIER_3 = 100 - iPercentCustomersInC_TIER_1 - iPercentCustomersInC_TIER_2;
|
||||
|
||||
// Percentages used when generating C_DOB
|
||||
const int iPercentUnder18 = 5;
|
||||
const int iPercentBetween19And24 = 16;
|
||||
const int iPercentBetween25And34 = 17;
|
||||
const int iPercentBetween35And44 = 19;
|
||||
const int iPercentBetween45And54 = 16;
|
||||
const int iPercentBetween55And64 = 11;
|
||||
const int iPercentBetween65And74 = 8;
|
||||
const int iPercentBetween75And84 = 7;
|
||||
const int iPercentOver85 = 1;
|
||||
|
||||
// Number of RNG calls to skip for one row in order
|
||||
// to not use any of the random values from the previous row.
|
||||
const int iRNGSkipOneRowCustomer = 35; // real max count in v3.5: 29
|
||||
|
||||
/*
|
||||
* CCustomerTable constructor
|
||||
*/
|
||||
CCustomerTable::CCustomerTable(const DataFileManager &dfm, TIdent iCustomerCount, TIdent iStartFromCustomer)
|
||||
: TableTemplate<CUSTOMER_ROW>(), m_iRowsToGenerate(iCustomerCount), m_person(dfm, iStartFromCustomer, true),
|
||||
m_Phones(dfm.AreaCodeDataFile()), m_iStartFromCustomer(iStartFromCustomer), m_iCustomerCount(iCustomerCount),
|
||||
m_StatusTypeFile(dfm.StatusTypeDataFile()), m_CustomerSelection() {
|
||||
m_iCompanyCount = dfm.CompanyFile().GetSize();
|
||||
m_iExchangeCount = dfm.ExchangeDataFile().size();
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the state for the next load unit
|
||||
*/
|
||||
void CCustomerTable::InitNextLoadUnit() {
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedTableDefault,
|
||||
((RNGSEED)m_iLastRowNumber + m_iStartFromCustomer - 1) * iRNGSkipOneRowCustomer));
|
||||
|
||||
ClearRecord(); // this is needed for EGenTest to work
|
||||
|
||||
m_person.InitNextLoadUnit();
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates only the next Customer ID value
|
||||
*/
|
||||
TIdent CCustomerTable::GenerateNextC_ID() {
|
||||
if (m_iLastRowNumber % iDefaultLoadUnitSize == 0) {
|
||||
InitNextLoadUnit();
|
||||
}
|
||||
|
||||
++m_iLastRowNumber; // increment state info
|
||||
m_bMoreRecords = m_iLastRowNumber < m_iRowsToGenerate;
|
||||
|
||||
m_row.C_ID = m_iLastRowNumber + m_iStartFromCustomer - 1 + iTIdentShift;
|
||||
|
||||
return m_row.C_ID;
|
||||
}
|
||||
/*
|
||||
* Return current customer id.
|
||||
*/
|
||||
TIdent CCustomerTable::GetCurrentC_ID() {
|
||||
return m_iLastRowNumber + m_iStartFromCustomer - 1 + iTIdentShift;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate tax id.
|
||||
*/
|
||||
void CCustomerTable::GetC_TAX_ID(TIdent C_ID, char *szOutput) {
|
||||
m_person.GetTaxID(C_ID, szOutput);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_ST_ID.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_ST_ID() {
|
||||
strncpy(m_row.C_ST_ID, m_StatusTypeFile[eActive].ST_ID_CSTR(), sizeof(m_row.C_ST_ID));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate first, last name, and the gender.
|
||||
*/
|
||||
void CCustomerTable::GeneratePersonInfo() {
|
||||
// Fill in the first name, last name, and the tax id
|
||||
m_person.GetFirstLastAndTaxID(m_row.C_ID, m_row.C_F_NAME, m_row.C_L_NAME, m_row.C_TAX_ID);
|
||||
// Fill in the gender
|
||||
m_row.C_GNDR = m_person.GetGender(m_row.C_ID);
|
||||
// Fill in the middle name
|
||||
m_row.C_M_NAME[0] = m_person.GetMiddleName(m_row.C_ID);
|
||||
m_row.C_M_NAME[1] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_TIER.
|
||||
*/
|
||||
eCustomerTier CCustomerTable::GetC_TIER(TIdent C_ID) {
|
||||
return m_CustomerSelection.GetTier(C_ID);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate date of birth.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_DOB() {
|
||||
// min and max age brackets limits in years
|
||||
static int age_brackets[] = {10, 19, 25, 35, 45, 55, 65, 75, 85, 100};
|
||||
int age_bracket;
|
||||
int dob_daysno_min, dob_daysno_max; // min and max date of birth in days
|
||||
int dob_in_days; // generated random date of birth in days
|
||||
|
||||
int iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
|
||||
// Determine customer age bracket according to the distribution.
|
||||
if (iThreshold <= iPercentUnder18)
|
||||
age_bracket = 0;
|
||||
else if (iThreshold <= iPercentUnder18 + iPercentBetween19And24)
|
||||
age_bracket = 1;
|
||||
else if (iThreshold <= iPercentUnder18 + iPercentBetween19And24 + iPercentBetween25And34)
|
||||
age_bracket = 2;
|
||||
else if (iThreshold <= iPercentUnder18 + iPercentBetween19And24 + iPercentBetween25And34 + iPercentBetween35And44)
|
||||
age_bracket = 3;
|
||||
else if (iThreshold <= iPercentUnder18 + iPercentBetween19And24 + iPercentBetween25And34 + iPercentBetween35And44 +
|
||||
iPercentBetween45And54)
|
||||
age_bracket = 4;
|
||||
else if (iThreshold <= iPercentUnder18 + iPercentBetween19And24 + iPercentBetween25And34 + iPercentBetween35And44 +
|
||||
iPercentBetween45And54 + iPercentBetween55And64)
|
||||
age_bracket = 5;
|
||||
else if (iThreshold <= iPercentUnder18 + iPercentBetween19And24 + iPercentBetween25And34 + iPercentBetween35And44 +
|
||||
iPercentBetween45And54 + iPercentBetween55And64 + iPercentBetween65And74)
|
||||
age_bracket = 6;
|
||||
else if (iThreshold <= iPercentUnder18 + iPercentBetween19And24 + iPercentBetween25And34 + iPercentBetween35And44 +
|
||||
iPercentBetween45And54 + iPercentBetween55And64 + iPercentBetween65And74 +
|
||||
iPercentBetween75And84)
|
||||
age_bracket = 7;
|
||||
else
|
||||
age_bracket = 8;
|
||||
assert(age_bracket < static_cast<int>(sizeof(age_brackets) / sizeof(age_brackets[0])));
|
||||
|
||||
// Determine the range of valid day numbers for this person's birthday.
|
||||
dob_daysno_min = CDateTime::YMDtoDayno(InitialTradePopulationBaseYear - age_brackets[age_bracket + 1],
|
||||
InitialTradePopulationBaseMonth, InitialTradePopulationBaseDay) +
|
||||
1;
|
||||
dob_daysno_max = CDateTime::YMDtoDayno(InitialTradePopulationBaseYear - age_brackets[age_bracket],
|
||||
InitialTradePopulationBaseMonth, InitialTradePopulationBaseDay);
|
||||
|
||||
// Generate the random age expressed in days that falls into the particular
|
||||
// range.
|
||||
dob_in_days = m_rnd.RndIntRange(dob_daysno_min, dob_daysno_max);
|
||||
|
||||
m_row.C_DOB.Set(dob_in_days);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_AD_ID (address id).
|
||||
*/
|
||||
void CCustomerTable::GenerateC_AD_ID() {
|
||||
// Generate address id sequentially, allowing space for Exchanges and
|
||||
// Companies in the beggining of the address ids range.
|
||||
m_row.C_AD_ID = m_iExchangeCount + m_iCompanyCount + GetCurrentC_ID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_CTRY_1.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_CTRY_1() {
|
||||
strncpy(m_row.C_CTRY_1, szUSAreaCode, sizeof(m_row.C_CTRY_1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_CTRY_2.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_CTRY_2() {
|
||||
strncpy(m_row.C_CTRY_2, szUSAreaCode, sizeof(m_row.C_CTRY_2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_CTRY_3.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_CTRY_3() {
|
||||
strncpy(m_row.C_CTRY_3, szUSAreaCode, sizeof(m_row.C_CTRY_3));
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_AREA_1
|
||||
*/
|
||||
void CCustomerTable::GenerateC_AREA_1() {
|
||||
RNGSEED OldSeed;
|
||||
int iThreshold;
|
||||
|
||||
OldSeed = m_rnd.GetSeed();
|
||||
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseC_AREA_1, (RNGSEED)m_row.C_ID));
|
||||
|
||||
// generate Threshold up to the value of the last key (first member in a
|
||||
// pair)
|
||||
iThreshold = m_rnd.RndIntRange(0, m_Phones.size() - 1);
|
||||
|
||||
// copy the area code that corresponds to the Threshold
|
||||
strncpy(m_row.C_AREA_1, m_Phones[iThreshold].AREA_CODE_CSTR(), sizeof(m_row.C_AREA_1));
|
||||
|
||||
m_rnd.SetSeed(OldSeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_AREA_2
|
||||
*/
|
||||
void CCustomerTable::GenerateC_AREA_2() {
|
||||
RNGSEED OldSeed;
|
||||
int iThreshold;
|
||||
|
||||
OldSeed = m_rnd.GetSeed();
|
||||
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseC_AREA_2, (RNGSEED)m_row.C_ID));
|
||||
|
||||
// generate Threshold up to the value of the last key (first member in a
|
||||
// pair)
|
||||
iThreshold = m_rnd.RndIntRange(0, m_Phones.size() - 1);
|
||||
|
||||
// copy the area code that corresponds to the Threshold
|
||||
strncpy(m_row.C_AREA_2, m_Phones[iThreshold].AREA_CODE_CSTR(), sizeof(m_row.C_AREA_2));
|
||||
|
||||
m_rnd.SetSeed(OldSeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_AREA_3
|
||||
*/
|
||||
void CCustomerTable::GenerateC_AREA_3() {
|
||||
RNGSEED OldSeed;
|
||||
int iThreshold;
|
||||
|
||||
OldSeed = m_rnd.GetSeed();
|
||||
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseC_AREA_3, (RNGSEED)m_row.C_ID));
|
||||
|
||||
// generate Threshold up to the value of the last key (first member in a
|
||||
// pair)
|
||||
iThreshold = m_rnd.RndIntRange(0, m_Phones.size() - 1);
|
||||
|
||||
// copy the area code that corresponds to the Threshold
|
||||
strncpy(m_row.C_AREA_3, m_Phones[iThreshold].AREA_CODE_CSTR(), sizeof(m_row.C_AREA_3));
|
||||
|
||||
m_rnd.SetSeed(OldSeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_LOCAL_1.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_LOCAL_1() {
|
||||
m_rnd.RndAlphaNumFormatted(m_row.C_LOCAL_1,
|
||||
"nnnnnnn"); // 7-digit phone number
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_LOCAL_2.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_LOCAL_2() {
|
||||
m_rnd.RndAlphaNumFormatted(m_row.C_LOCAL_2,
|
||||
"nnnnnnn"); // 7-digit phone number
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_LOCAL_3.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_LOCAL_3() {
|
||||
m_rnd.RndAlphaNumFormatted(m_row.C_LOCAL_3,
|
||||
"nnnnnnn"); // 7-digit phone number
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_EXT_1.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_EXT_1() {
|
||||
int iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
|
||||
if (iThreshold <= 25) {
|
||||
m_rnd.RndAlphaNumFormatted(m_row.C_EXT_1,
|
||||
"nnn"); // 3-digit phone extension
|
||||
} else {
|
||||
*m_row.C_EXT_1 = '\0'; // no extension
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_EXT_2.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_EXT_2() {
|
||||
int iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
|
||||
if (iThreshold <= 15) {
|
||||
m_rnd.RndAlphaNumFormatted(m_row.C_EXT_2,
|
||||
"nnn"); // 3-digit phone extension
|
||||
} else {
|
||||
*m_row.C_EXT_2 = '\0'; // no extension
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate C_EXT_3.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_EXT_3() {
|
||||
int iThreshold = m_rnd.RndGenerateIntegerPercentage();
|
||||
|
||||
if (iThreshold <= 5) {
|
||||
m_rnd.RndAlphaNumFormatted(m_row.C_EXT_3,
|
||||
"nnn"); // 3-digit phone extension
|
||||
} else {
|
||||
*m_row.C_EXT_3 = '\0'; // no extension
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Email 1 and Email 2 that are guaranteed to be different.
|
||||
*/
|
||||
void CCustomerTable::GenerateC_EMAIL_1_and_C_EMAIL_2() {
|
||||
size_t iLen;
|
||||
int iEmail1Index;
|
||||
|
||||
iEmail1Index = m_rnd.RndIntRange(0, iNumEMAIL_DOMAINs - 1);
|
||||
|
||||
// Generate EMAIL_1
|
||||
iLen = strlen(m_row.C_L_NAME);
|
||||
m_row.C_EMAIL_1[0] = m_row.C_F_NAME[0]; // first char of the first name
|
||||
strncpy(&m_row.C_EMAIL_1[1], m_row.C_L_NAME, // last name
|
||||
sizeof(m_row.C_EMAIL_1) - 1);
|
||||
strncpy(&m_row.C_EMAIL_1[1 + iLen],
|
||||
EMAIL_DOMAINs[iEmail1Index], // domain name
|
||||
sizeof(m_row.C_EMAIL_1) - iLen - 1);
|
||||
|
||||
// Generate EMAIL_2 that is different from EMAIL_1
|
||||
m_row.C_EMAIL_2[0] = m_row.C_F_NAME[0]; // first char of the first name
|
||||
strncpy(&m_row.C_EMAIL_2[1], m_row.C_L_NAME,
|
||||
sizeof(m_row.C_EMAIL_2) - 1); // last name
|
||||
strncpy(&m_row.C_EMAIL_2[1 + iLen],
|
||||
EMAIL_DOMAINs[m_rnd.RndIntRangeExclude(0, iNumEMAIL_DOMAINs - 1, iEmail1Index)], // domain name
|
||||
sizeof(m_row.C_EMAIL_2) - iLen - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates all column values for the next row
|
||||
*/
|
||||
bool CCustomerTable::GenerateNextRecord() {
|
||||
GenerateNextC_ID();
|
||||
GenerateC_ST_ID();
|
||||
GeneratePersonInfo(); // generate last name, first name, gender and tax ID.
|
||||
m_row.C_TIER = (char)GetC_TIER(m_row.C_ID);
|
||||
GenerateC_DOB();
|
||||
GenerateC_AD_ID();
|
||||
GenerateC_CTRY_1();
|
||||
GenerateC_AREA_1();
|
||||
GenerateC_LOCAL_1();
|
||||
GenerateC_EXT_1();
|
||||
GenerateC_CTRY_2();
|
||||
GenerateC_AREA_2();
|
||||
GenerateC_LOCAL_2();
|
||||
GenerateC_EXT_2();
|
||||
GenerateC_CTRY_3();
|
||||
GenerateC_AREA_3();
|
||||
GenerateC_LOCAL_3();
|
||||
GenerateC_EXT_3();
|
||||
GenerateC_EMAIL_1_and_C_EMAIL_2();
|
||||
|
||||
// Return false if all the rows have been generated
|
||||
return MoreRecords();
|
||||
}
|
||||
268
external/duckdb/third_party/tpce-tool/main/DM.cpp
vendored
Normal file
268
external/duckdb/third_party/tpce-tool/main/DM.cpp
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson, Matt Emmerton
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of the DM class.
|
||||
* See DM.h for a description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/DM.h"
|
||||
#include "main/StatusTypeIDs.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
const INT32 iDataMaintenanceTableCount = 12;
|
||||
static const char *DataMaintenanceTableName[iDataMaintenanceTableCount] = {
|
||||
"ACCOUNT_PERMISSION", "ADDRESS", "COMPANY", "CUSTOMER", "CUSTOMER_TAXRATE", "DAILY_MARKET",
|
||||
"EXCHANGE", "FINANCIAL", "NEWS_ITEM", "SECURITY", "TAXRATE", "WATCH_ITEM"};
|
||||
|
||||
// Automatically generate unique RNG seeds.
|
||||
// The CRandom class uses an unsigned 64-bit value for the seed.
|
||||
// This routine automatically generates two unique seeds. One is used for
|
||||
// the TxnInput generator RNG, and the other is for the TxnMixGenerator RNG.
|
||||
// The 64 bits are used as follows.
|
||||
//
|
||||
// Bits 0 - 31 Caller provided unique unsigned 32-bit id.
|
||||
// Bit 32 0
|
||||
// Bits 33 - 43 Number of days since the base time. The base time
|
||||
// is set to be January 1 of the most recent year that is
|
||||
// a multiple of 5. This allows enough space for the last
|
||||
// field, and it makes the algorithm "timeless" by resetting
|
||||
// the generated values every 5 years.
|
||||
// Bits 44 - 63 Current time of day measured in 1/10's of a second.
|
||||
//
|
||||
void CDM::AutoSetRNGSeeds(UINT32 UniqueId) {
|
||||
CDateTime Now;
|
||||
INT32 BaseYear;
|
||||
INT32 Tmp1, Tmp2;
|
||||
|
||||
Now.GetYMD(&BaseYear, &Tmp1, &Tmp2);
|
||||
|
||||
// Set the base year to be the most recent year that was a multiple of 5.
|
||||
BaseYear -= (BaseYear % 5);
|
||||
CDateTime Base(BaseYear, 1, 1); // January 1st in the BaseYear
|
||||
|
||||
// Initialize the seed with the current time of day measured in 1/10's of a
|
||||
// second. This will use up to 20 bits.
|
||||
RNGSEED Seed;
|
||||
Seed = Now.MSec() / 100;
|
||||
|
||||
// Now add in the number of days since the base time.
|
||||
// The number of days in the 5 year period requires 11 bits.
|
||||
// So shift up by that much to make room in the "lower" bits.
|
||||
Seed <<= 11;
|
||||
Seed += (RNGSEED)((INT64)Now.DayNo() - (INT64)Base.DayNo());
|
||||
|
||||
// So far, we've used up 31 bits.
|
||||
// Save the "last" bit of the "upper" 32 for the RNG id. In
|
||||
// this case, it is always 0 since we don't have a second
|
||||
// RNG in this class.
|
||||
// In addition, make room for the caller's 32-bit unique id.
|
||||
// So shift a total of 33 bits.
|
||||
Seed <<= 33;
|
||||
|
||||
// Now the "upper" 32-bits have been set with a value for RNG 0.
|
||||
// Add in the sponsor's unique id for the "lower" 32-bits.
|
||||
Seed += UniqueId;
|
||||
|
||||
// Set the RNG to the unique seed.
|
||||
m_rnd.SetSeed(Seed);
|
||||
m_DriverDMSettings.cur.RNGSeed = Seed;
|
||||
}
|
||||
|
||||
void CDM::Initialize(void) {
|
||||
m_pLogger->SendToLogger(m_DriverGlobalSettings);
|
||||
|
||||
m_iSecurityCount = m_Securities.GetActiveSecurityCount();
|
||||
m_iCompanyCount = m_Companies.GetActiveCompanyCount();
|
||||
m_iStartFromCompany = m_Companies.GetCompanyId(0);
|
||||
m_iDivisionTaxCount = m_TaxRatesDivision.size(m_TaxRatesDivision.BucketsOnly);
|
||||
m_iStartFromCustomer = iDefaultStartFromCustomer + iTIdentShift;
|
||||
}
|
||||
|
||||
CDM::CDM(CDMSUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iDaysOfInitialTrades, UINT32 UniqueId)
|
||||
: m_DriverGlobalSettings(iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor, iDaysOfInitialTrades),
|
||||
m_DriverDMSettings(UniqueId, 0), m_CustomerSelection(&m_rnd, iDefaultStartFromCustomer, iActiveCustomerCount),
|
||||
m_AccsAndPerms(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Securities(dfm.SecurityFile()), m_Companies(dfm.CompanyFile()),
|
||||
m_TaxRatesDivision(dfm.TaxRateDivisionDataFile()), m_StatusType(dfm.StatusTypeDataFile()), m_iDivisionTaxCount(0),
|
||||
m_DataMaintenanceTableNum(0), m_pSUT(pSUT), m_pLogger(pLogger) {
|
||||
m_pLogger->SendToLogger("DM object constructed using constructor 1 (valid "
|
||||
"for publication: YES).");
|
||||
|
||||
Initialize();
|
||||
AutoSetRNGSeeds(UniqueId);
|
||||
|
||||
m_pLogger->SendToLogger(m_DriverDMSettings); // log the RNG seeds
|
||||
}
|
||||
|
||||
CDM::CDM(CDMSUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm, TIdent iConfiguredCustomerCount,
|
||||
TIdent iActiveCustomerCount, INT32 iScaleFactor, INT32 iDaysOfInitialTrades, UINT32 UniqueId, RNGSEED RNGSeed)
|
||||
: m_DriverGlobalSettings(iConfiguredCustomerCount, iActiveCustomerCount, iScaleFactor, iDaysOfInitialTrades),
|
||||
m_DriverDMSettings(UniqueId, RNGSeed), m_rnd(RNGSeed),
|
||||
m_CustomerSelection(&m_rnd, iDefaultStartFromCustomer, iActiveCustomerCount),
|
||||
m_AccsAndPerms(dfm, iDefaultLoadUnitSize, iActiveCustomerCount, iDefaultStartFromCustomer),
|
||||
m_Securities(dfm.SecurityFile()), m_Companies(dfm.CompanyFile()),
|
||||
m_TaxRatesDivision(dfm.TaxRateDivisionDataFile()), m_StatusType(dfm.StatusTypeDataFile()), m_iDivisionTaxCount(0),
|
||||
m_DataMaintenanceTableNum(0), m_pSUT(pSUT), m_pLogger(pLogger) {
|
||||
m_pLogger->SendToLogger("DM object constructed using constructor 2 (valid "
|
||||
"for publication: NO).");
|
||||
|
||||
Initialize();
|
||||
|
||||
m_pLogger->SendToLogger(m_DriverDMSettings); // log the RNG seeds
|
||||
}
|
||||
|
||||
CDM::~CDM() {
|
||||
m_pLogger->SendToLogger("DM object destroyed.");
|
||||
}
|
||||
|
||||
TIdent CDM::GenerateRandomCustomerId() {
|
||||
return m_rnd.RndInt64Range(m_iStartFromCustomer,
|
||||
m_iStartFromCustomer + m_DriverGlobalSettings.cur.iActiveCustomerCount - 1);
|
||||
}
|
||||
|
||||
TIdent CDM::GenerateRandomCustomerAccountId() {
|
||||
TIdent iCustomerId;
|
||||
|
||||
eCustomerTier iCustomerTier;
|
||||
|
||||
m_CustomerSelection.GenerateRandomCustomer(iCustomerId, iCustomerTier);
|
||||
|
||||
return (m_AccsAndPerms.GenerateRandomAccountId(m_rnd, iCustomerId, iCustomerTier));
|
||||
}
|
||||
|
||||
TIdent CDM::GenerateRandomCompanyId() {
|
||||
return m_rnd.RndInt64Range(m_iStartFromCompany, m_iStartFromCompany + m_iCompanyCount - 1);
|
||||
}
|
||||
|
||||
TIdent CDM::GenerateRandomSecurityId() {
|
||||
return m_rnd.RndInt64Range(0, m_iSecurityCount - 1);
|
||||
}
|
||||
|
||||
RNGSEED CDM::GetRNGSeed(void) {
|
||||
return (m_rnd.GetSeed());
|
||||
}
|
||||
|
||||
void CDM::DoTxn(void) {
|
||||
m_TxnInput.Clear();
|
||||
strncpy(m_TxnInput.table_name, DataMaintenanceTableName[m_DataMaintenanceTableNum], sizeof(m_TxnInput.table_name));
|
||||
|
||||
switch (m_DataMaintenanceTableNum) {
|
||||
case 0: // ACCOUNT_PERMISSION
|
||||
m_TxnInput.acct_id = GenerateRandomCustomerAccountId();
|
||||
break;
|
||||
case 1: // ADDRESS
|
||||
if (m_rnd.RndPercent(67)) {
|
||||
m_TxnInput.c_id = GenerateRandomCustomerId();
|
||||
} else {
|
||||
m_TxnInput.co_id = GenerateRandomCompanyId();
|
||||
}
|
||||
break;
|
||||
case 2: // COMPANY
|
||||
m_TxnInput.co_id = GenerateRandomCompanyId();
|
||||
break;
|
||||
case 3: // CUSTOMER
|
||||
m_TxnInput.c_id = GenerateRandomCustomerId();
|
||||
break;
|
||||
case 4: // CUSTOMER_TAXRATE
|
||||
m_TxnInput.c_id = GenerateRandomCustomerId();
|
||||
break;
|
||||
case 5: // DAILY_MARKET
|
||||
m_Securities.CreateSymbol(GenerateRandomSecurityId(), m_TxnInput.symbol,
|
||||
static_cast<int>(sizeof(m_TxnInput.symbol)));
|
||||
m_TxnInput.day_of_month = m_rnd.RndIntRange(1, 31);
|
||||
m_TxnInput.vol_incr = m_rnd.RndIntRange(-2, 3);
|
||||
if (m_TxnInput.vol_incr == 0) // don't want 0 as increment
|
||||
{
|
||||
m_TxnInput.vol_incr = -3;
|
||||
}
|
||||
break;
|
||||
case 6: // EXCHANGE
|
||||
break;
|
||||
case 7: // FINANCIAL
|
||||
m_TxnInput.co_id = GenerateRandomCompanyId();
|
||||
break;
|
||||
case 8: // NEWS_ITEM
|
||||
m_TxnInput.co_id = GenerateRandomCompanyId();
|
||||
break;
|
||||
case 9: // SECURITY
|
||||
m_Securities.CreateSymbol(GenerateRandomSecurityId(), m_TxnInput.symbol,
|
||||
static_cast<int>(sizeof(m_TxnInput.symbol)));
|
||||
break;
|
||||
case 10: // TAXRATE
|
||||
{
|
||||
UINT bucketIdx = static_cast<UINT>(m_rnd.RndIntRange(0, m_iDivisionTaxCount - 1));
|
||||
UINT recordIdx = static_cast<UINT>(m_rnd.RndIntRange(0, m_TaxRatesDivision[bucketIdx].size() - 1));
|
||||
|
||||
strncpy(m_TxnInput.tx_id, m_TaxRatesDivision[bucketIdx][recordIdx].TX_ID_CSTR(), sizeof(m_TxnInput.tx_id));
|
||||
} break;
|
||||
case 11: // WATCH_ITEM
|
||||
m_TxnInput.c_id = GenerateRandomCustomerId();
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false); // should never happen
|
||||
}
|
||||
|
||||
m_pSUT->DataMaintenance(&m_TxnInput);
|
||||
|
||||
m_DataMaintenanceTableNum = (m_DataMaintenanceTableNum + 1) % iDataMaintenanceTableCount;
|
||||
}
|
||||
|
||||
void CDM::DoCleanupTxn(void) {
|
||||
memset(&m_CleanupTxnInput, 0, sizeof(m_CleanupTxnInput));
|
||||
|
||||
// Compute Starting Trade ID (Copied from CETxnInputGenerator.cpp)
|
||||
m_CleanupTxnInput.start_trade_id =
|
||||
(TTrade)((m_DriverGlobalSettings.cur.iDaysOfInitialTrades * (TTrade)HoursPerWorkDay * (TTrade)SecondsPerHour *
|
||||
(m_DriverGlobalSettings.cur.iConfiguredCustomerCount / m_DriverGlobalSettings.cur.iScaleFactor)) *
|
||||
iAbortTrade / 100) +
|
||||
1 + iTTradeShift; // 1.01 to account for rollbacks, +1 to get first
|
||||
// runtime trade
|
||||
|
||||
// Copy the status type id's from the flat file
|
||||
strncpy(m_CleanupTxnInput.st_pending_id, m_StatusType[ePending].ST_ID_CSTR(),
|
||||
sizeof(m_CleanupTxnInput.st_pending_id));
|
||||
strncpy(m_CleanupTxnInput.st_submitted_id, m_StatusType[eSubmitted].ST_ID_CSTR(),
|
||||
sizeof(m_CleanupTxnInput.st_submitted_id));
|
||||
strncpy(m_CleanupTxnInput.st_canceled_id, m_StatusType[eCanceled].ST_ID_CSTR(),
|
||||
sizeof(m_CleanupTxnInput.st_canceled_id));
|
||||
|
||||
// Execute Transaction
|
||||
m_pSUT->TradeCleanup(&m_CleanupTxnInput);
|
||||
}
|
||||
1114
external/duckdb/third_party/tpce-tool/main/EGenGenerateAndLoad.cpp
vendored
Normal file
1114
external/duckdb/third_party/tpce-tool/main/EGenGenerateAndLoad.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
575
external/duckdb/third_party/tpce-tool/main/EGenLoader.cpp
vendored
Normal file
575
external/duckdb/third_party/tpce-tool/main/EGenLoader.cpp
vendored
Normal file
@@ -0,0 +1,575 @@
|
||||
/*
|
||||
* 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
|
||||
* - Sergey Vasilevskiy, Matt Emmerton, Doug Johnson
|
||||
*/
|
||||
|
||||
//
|
||||
// Defines the entry point for the console application.
|
||||
//
|
||||
#include <string>
|
||||
|
||||
#include "main/EGenLoader_stdafx.h"
|
||||
#include "input/DataFileManager.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
// Driver Defaults
|
||||
TIdent iStartFromCustomer = iDefaultStartFromCustomer;
|
||||
TIdent iCustomerCount = iDefaultCustomerCount; // # of customers for this instance
|
||||
TIdent iTotalCustomerCount = iDefaultCustomerCount; // total number of customers in the database
|
||||
UINT iLoadUnitSize = iDefaultLoadUnitSize; // # of customers in one load unit
|
||||
UINT iScaleFactor = 500; // # of customers for 1 tpsE
|
||||
UINT iDaysOfInitialTrades = 300;
|
||||
|
||||
// These flags are used to control which tables get generated and loaded.
|
||||
bool bTableGenerationFlagNotSpecified = true; // assume no flag is specified.
|
||||
bool bGenerateFixedTables = false;
|
||||
bool bGenerateGrowingTables = false;
|
||||
bool bGenerateScalingTables = false;
|
||||
bool bGenerateUsingCache = true;
|
||||
|
||||
char szInDir[iMaxPath];
|
||||
#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
char szOutDir[iMaxPath];
|
||||
FlatFileOutputModes FlatFileOutputMode;
|
||||
#endif
|
||||
#ifdef COMPILE_ODBC_LOAD
|
||||
char szServer[iMaxHostname];
|
||||
char szDB[iMaxDBName];
|
||||
#endif
|
||||
#if defined(COMPILE_ODBC_LOAD) || defined(COMPILE_CUSTOM_LOAD)
|
||||
char szLoaderParms[1024];
|
||||
#endif
|
||||
|
||||
#ifndef FLAT_IN_PATH
|
||||
#define FLAT_IN_PATH "flat_in/"
|
||||
#endif
|
||||
|
||||
#ifndef FLAT_OUT_PATH
|
||||
#define FLAT_OUT_PATH "flat_out/"
|
||||
#endif
|
||||
|
||||
enum eLoadImplementation {
|
||||
NULL_LOAD = 0, // no load - generate data only
|
||||
FLAT_FILE_LOAD,
|
||||
ODBC_LOAD,
|
||||
CUSTOM_LOAD // sponsor-provided load mechanism
|
||||
};
|
||||
#if defined(DEFAULT_LOAD_TYPE)
|
||||
eLoadImplementation LoadType = DEFAULT_LOAD_TYPE;
|
||||
#elif defined(COMPILE_FLAT_FILE_LOAD)
|
||||
eLoadImplementation LoadType = FLAT_FILE_LOAD;
|
||||
#elif defined(COMPILE_ODBC_LOAD)
|
||||
eLoadImplementation LoadType = ODBC_LOAD;
|
||||
#elif defined(COMPILE_CUSTOM_LOAD)
|
||||
eLoadImplementation LoadType = CUSTOM_LOAD;
|
||||
#else
|
||||
eLoadImplementation LoadType = NULL_LOAD;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prints program usage to std error.
|
||||
*/
|
||||
void Usage() {
|
||||
fprintf(stderr, "Usage:\n");
|
||||
fprintf(stderr, "EGenLoader [options] \n\n");
|
||||
fprintf(stderr, " Where\n");
|
||||
fprintf(stderr, " Option Default Description\n");
|
||||
fprintf(stderr, " -b number %" PRId64 " Beginning customer ordinal position\n",
|
||||
iStartFromCustomer);
|
||||
fprintf(stderr, " -c number %" PRId64 " Number of customers (for this instance)\n",
|
||||
iCustomerCount);
|
||||
fprintf(stderr, " -t number %" PRId64 " Number of customers (total in the database)\n",
|
||||
iTotalCustomerCount);
|
||||
fprintf(stderr,
|
||||
" -f number %d Scale factor (customers "
|
||||
"per 1 tpsE)\n",
|
||||
iScaleFactor);
|
||||
fprintf(stderr,
|
||||
" -w number %d Number of Workdays "
|
||||
"(8-hour days) of \n",
|
||||
iDaysOfInitialTrades);
|
||||
fprintf(stderr, " initial trades "
|
||||
"to populate\n");
|
||||
fprintf(stderr, " -i dir %-11s Directory for input files\n", FLAT_IN_PATH);
|
||||
fprintf(stderr, " -l [FLAT|ODBC|CUSTOM|NULL] FLAT Type of load\n");
|
||||
#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
fprintf(stderr, " -m [APPEND|OVERWRITE] OVERWRITE Flat File output mode\n");
|
||||
fprintf(stderr, " -o dir %-11s Directory for output files\n", FLAT_OUT_PATH);
|
||||
#endif
|
||||
#ifdef COMPILE_ODBC_LOAD
|
||||
fprintf(stderr, " -s string localhost Database server\n");
|
||||
fprintf(stderr, " -d string tpce Database name\n");
|
||||
#endif
|
||||
#if defined(COMPILE_ODBC_LOAD) || defined(COMPILE_CUSTOM_LOAD)
|
||||
fprintf(stderr, " -p string Additional "
|
||||
"parameters to loader\n");
|
||||
#endif
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -x -x Generate all tables\n");
|
||||
fprintf(stderr, " -xf Generate all "
|
||||
"fixed-size tables\n");
|
||||
fprintf(stderr, " -xd Generate all "
|
||||
"scaling and growing tables\n");
|
||||
fprintf(stderr, " (equivalent to -xs -xg)\n");
|
||||
fprintf(stderr, " -xs Generate scaling tables\n");
|
||||
fprintf(stderr, " (except BROKER)\n");
|
||||
fprintf(stderr, " -xg Generate "
|
||||
"growing tables and BROKER\n");
|
||||
fprintf(stderr, " -g Disable "
|
||||
"caching when generating growing tables\n");
|
||||
}
|
||||
|
||||
void ParseCommandLine(int argc, char *argv[]) {
|
||||
int arg;
|
||||
char *sp;
|
||||
char *vp;
|
||||
|
||||
/*
|
||||
* Scan the command line arguments
|
||||
*/
|
||||
for (arg = 1; arg < argc; ++arg) {
|
||||
|
||||
/*
|
||||
* Look for a switch
|
||||
*/
|
||||
sp = argv[arg];
|
||||
if (*sp == '-') {
|
||||
++sp;
|
||||
}
|
||||
*sp = (char)tolower(*sp);
|
||||
|
||||
/*
|
||||
* Find the switch's argument. It is either immediately after the
|
||||
* switch or in the next argv
|
||||
*/
|
||||
vp = sp + 1;
|
||||
// Allow for switched that don't have any parameters.
|
||||
// Need to check that the next argument is in fact a parameter
|
||||
// and not the next switch that starts with '-'.
|
||||
//
|
||||
if ((*vp == 0) && ((arg + 1) < argc) && (argv[arg + 1][0] != '-')) {
|
||||
vp = argv[++arg];
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the switch
|
||||
*/
|
||||
switch (*sp) {
|
||||
case 'b':
|
||||
sscanf(vp, "%" PRId64, &iStartFromCustomer);
|
||||
if (iStartFromCustomer <= 0) { // set back to default
|
||||
// either number parsing was unsuccessful
|
||||
// or a bad value was specified
|
||||
iStartFromCustomer = iDefaultStartFromCustomer;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
sscanf(vp, "%" PRId64, &iCustomerCount);
|
||||
break;
|
||||
case 't':
|
||||
sscanf(vp, "%" PRId64, &iTotalCustomerCount);
|
||||
break;
|
||||
case 'f':
|
||||
iScaleFactor = (UINT)atoi(vp);
|
||||
break;
|
||||
case 'w':
|
||||
iDaysOfInitialTrades = (UINT)atoi(vp);
|
||||
break;
|
||||
|
||||
case 'i': // Location of input files.
|
||||
strncpy(szInDir, vp, sizeof(szInDir));
|
||||
if (('/' != szInDir[strlen(szInDir) - 1]) && ('\\' != szInDir[strlen(szInDir) - 1])) {
|
||||
strncat(szInDir, "/", sizeof(szInDir) - strlen(szInDir) - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l': // Load type.
|
||||
#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
if (0 == strcmp(vp, "FLAT")) {
|
||||
LoadType = FLAT_FILE_LOAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef COMPILE_ODBC_LOAD
|
||||
if (0 == strcmp(vp, "ODBC")) {
|
||||
LoadType = ODBC_LOAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (0 == strcmp(vp, "NULL")) {
|
||||
LoadType = NULL_LOAD;
|
||||
break;
|
||||
}
|
||||
#ifdef COMPILE_CUSTOM_LOAD
|
||||
if (0 == strcmp(vp, "CUSTOM")) {
|
||||
LoadType = CUSTOM_LOAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
Usage();
|
||||
exit(ERROR_BAD_OPTION);
|
||||
break;
|
||||
|
||||
#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
case 'm': // Mode for output of flat files.
|
||||
if (0 == strcmp(vp, "APPEND")) {
|
||||
FlatFileOutputMode = FLAT_FILE_OUTPUT_APPEND;
|
||||
} else if (0 == strcmp(vp, "OVERWRITE")) {
|
||||
FlatFileOutputMode = FLAT_FILE_OUTPUT_OVERWRITE;
|
||||
} else {
|
||||
Usage();
|
||||
exit(ERROR_BAD_OPTION);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o': // Location for output files.
|
||||
strncpy(szOutDir, vp, sizeof(szOutDir));
|
||||
if (('/' != szOutDir[strlen(szOutDir) - 1]) && ('\\' != szOutDir[strlen(szOutDir) - 1])) {
|
||||
strncat(szOutDir, "/", sizeof(szOutDir) - strlen(szOutDir) - 1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef COMPILE_ODBC_LOAD
|
||||
case 's': // Database server name.
|
||||
strncpy(szServer, vp, sizeof(szServer));
|
||||
break;
|
||||
|
||||
case 'd': // Database name.
|
||||
strncpy(szDB, vp, sizeof(szDB));
|
||||
break;
|
||||
#endif
|
||||
#if defined(COMPILE_ODBC_LOAD) || defined(COMPILE_CUSTOM_LOAD)
|
||||
case 'p': // Loader Parameters
|
||||
strncpy(szLoaderParms, vp, sizeof(szLoaderParms));
|
||||
break;
|
||||
#endif
|
||||
case 'g': // Disable Cache for Growing Tables (CTradeGen)
|
||||
bGenerateUsingCache = false;
|
||||
break;
|
||||
case 'x': // Table Generation
|
||||
bTableGenerationFlagNotSpecified = false; // A -x flag has been used
|
||||
|
||||
if (NULL == vp || *vp == '\0') {
|
||||
bGenerateFixedTables = true;
|
||||
bGenerateGrowingTables = true;
|
||||
bGenerateScalingTables = true;
|
||||
} else if (0 == strcmp(vp, "f")) {
|
||||
bGenerateFixedTables = true;
|
||||
} else if (0 == strcmp(vp, "g")) {
|
||||
bGenerateGrowingTables = true;
|
||||
} else if (0 == strcmp(vp, "s")) {
|
||||
bGenerateScalingTables = true;
|
||||
} else if (0 == strcmp(vp, "d")) {
|
||||
bGenerateGrowingTables = true;
|
||||
bGenerateScalingTables = true;
|
||||
} else {
|
||||
Usage();
|
||||
exit(ERROR_BAD_OPTION);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Usage();
|
||||
fprintf(stderr, "Error: Unrecognized option: %s\n", sp);
|
||||
exit(ERROR_BAD_OPTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function validates EGenLoader parameters that may have been
|
||||
* specified on the command line. It's purpose is to prevent passing of
|
||||
* parameter values that would cause the loader to produce incorrect data.
|
||||
*
|
||||
* Condition: needs to be called after ParseCommandLine.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* NONE
|
||||
*
|
||||
* RETURN:
|
||||
* true - if all parameters are valid
|
||||
* false - if at least one parameter is invalid
|
||||
*/
|
||||
bool ValidateParameters() {
|
||||
bool bRet = true;
|
||||
|
||||
// Starting customer must be a non-zero integral multiple of load unit size
|
||||
// + 1.
|
||||
//
|
||||
if ((iStartFromCustomer % iLoadUnitSize) != 1) {
|
||||
cout << "The specified starting customer (-b " << iStartFromCustomer
|
||||
<< ") must be a non-zero integral multiple of the load unit size (" << iLoadUnitSize << ") + 1." << endl;
|
||||
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
// Total number of customers in the database cannot be less
|
||||
// than the number of customers for this loader instance
|
||||
//
|
||||
if (iTotalCustomerCount < iStartFromCustomer + iCustomerCount - 1) {
|
||||
iTotalCustomerCount = iStartFromCustomer + iCustomerCount - 1;
|
||||
}
|
||||
|
||||
// Customer count must be a non-zero integral multiple of load unit size.
|
||||
//
|
||||
if ((iLoadUnitSize > iCustomerCount) || (0 != iCustomerCount % iLoadUnitSize)) {
|
||||
cout << "The specified customer count (-c " << iCustomerCount
|
||||
<< ") must be a non-zero integral multiple of the load unit size (" << iLoadUnitSize << ")." << endl;
|
||||
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
// Total customer count must be a non-zero integral multiple of load unit
|
||||
// size.
|
||||
//
|
||||
if ((iLoadUnitSize > iTotalCustomerCount) || (0 != iTotalCustomerCount % iLoadUnitSize)) {
|
||||
cout << "The total customer count (-t " << iTotalCustomerCount
|
||||
<< ") must be a non-zero integral multiple of the load unit size (" << iLoadUnitSize << ")." << endl;
|
||||
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
// Completed trades in 8 hours must be a non-zero integral multiple of 100
|
||||
// so that exactly 1% extra trade ids can be assigned to simulate aborts.
|
||||
//
|
||||
if ((INT64)(HoursPerWorkDay * SecondsPerHour * iLoadUnitSize / iScaleFactor) % 100 != 0) {
|
||||
cout << "Incompatible value for Scale Factor (-f) specified." << endl;
|
||||
cout << HoursPerWorkDay << " * " << SecondsPerHour << " * Load Unit Size (" << iLoadUnitSize
|
||||
<< ") / Scale Factor (" << iScaleFactor << ") must be integral multiple of 100." << endl;
|
||||
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
if (iDaysOfInitialTrades == 0) {
|
||||
cout << "The specified number of 8-Hour Workdays (-w " << (iDaysOfInitialTrades) << ") must be non-zero."
|
||||
<< endl;
|
||||
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create loader class factory corresponding to the
|
||||
* selected load type.
|
||||
*/
|
||||
CBaseLoaderFactory *CreateLoaderFactory(eLoadImplementation eLoadType) {
|
||||
switch (eLoadType) {
|
||||
case NULL_LOAD:
|
||||
return new CNullLoaderFactory();
|
||||
|
||||
#ifdef COMPILE_ODBC_LOAD
|
||||
case ODBC_LOAD:
|
||||
return new CODBCLoaderFactory(szServer, szDB, szLoaderParms);
|
||||
#endif // #ifdef COMPILE_ODBC_LOAD
|
||||
|
||||
#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
case FLAT_FILE_LOAD:
|
||||
return new CFlatLoaderFactory(szOutDir, FlatFileOutputMode);
|
||||
#endif //#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
|
||||
#ifdef COMPILE_CUSTOM_LOAD
|
||||
case CUSTOM_LOAD:
|
||||
return new CCustomLoaderFactory(szLoaderParms);
|
||||
#endif //#ifdef COMPILE_CUSTOM_FILE_LOAD
|
||||
|
||||
default:
|
||||
assert(false); // this should never happen
|
||||
}
|
||||
|
||||
return NULL; // should never happen
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
CBaseLoaderFactory *pLoaderFactory; // class factory that creates table loaders
|
||||
CGenerateAndLoadStandardOutput Output;
|
||||
CGenerateAndLoad *pGenerateAndLoad;
|
||||
CDateTime StartTime, EndTime, LoadTime; // to time the database load
|
||||
|
||||
// Output EGen version
|
||||
PrintEGenVersion();
|
||||
|
||||
// Establish defaults for command line options.
|
||||
#ifdef COMPILE_ODBC_LOAD
|
||||
strncpy(szServer, "localhost", sizeof(szServer));
|
||||
strncpy(szDB, "tpce", sizeof(szDB));
|
||||
#endif
|
||||
strncpy(szInDir, FLAT_IN_PATH, sizeof(szInDir));
|
||||
#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
strncpy(szOutDir, FLAT_OUT_PATH, sizeof(szOutDir));
|
||||
FlatFileOutputMode = FLAT_FILE_OUTPUT_OVERWRITE;
|
||||
#endif
|
||||
|
||||
// Get command line options.
|
||||
//
|
||||
ParseCommandLine(argc, argv);
|
||||
|
||||
// Validate global parameters that may have been modified on
|
||||
// the command line.
|
||||
//
|
||||
if (!ValidateParameters()) {
|
||||
return ERROR_INVALID_OPTION_VALUE; // exit from the loader returning a
|
||||
// non-zero code
|
||||
}
|
||||
|
||||
// Let the user know what settings will be used.
|
||||
cout << endl << endl << "Using the following settings." << endl << endl;
|
||||
switch (LoadType) {
|
||||
#ifdef COMPILE_ODBC_LOAD
|
||||
case ODBC_LOAD:
|
||||
cout << "\tLoad Type:\t\tODBC" << endl;
|
||||
cout << "\tServer Name:\t\t" << szServer << endl;
|
||||
cout << "\tDatabase:\t\t" << szDB << endl;
|
||||
break;
|
||||
#endif
|
||||
#ifdef COMPILE_FLAT_FILE_LOAD
|
||||
case FLAT_FILE_LOAD:
|
||||
cout << "\tLoad Type:\t\tFlat File" << endl;
|
||||
switch (FlatFileOutputMode) {
|
||||
case FLAT_FILE_OUTPUT_APPEND:
|
||||
cout << "\tOutput Mode:\t\tAPPEND" << endl;
|
||||
break;
|
||||
case FLAT_FILE_OUTPUT_OVERWRITE:
|
||||
cout << "\tOutput Mode:\t\tOVERWRITE" << endl;
|
||||
break;
|
||||
}
|
||||
cout << "\tOut Directory:\t\t" << szOutDir << endl;
|
||||
break;
|
||||
#endif
|
||||
#ifdef COMPILE_CUSTOM_LOAD
|
||||
case CUSTOM_LOAD:
|
||||
cout << "\tLoad Type:\t\tCustom" << endl;
|
||||
cout << "\tLoader Parms:\t\t" << szLoaderParms << endl;
|
||||
break;
|
||||
#endif
|
||||
case NULL_LOAD:
|
||||
default:
|
||||
cout << "\tLoad Type:\t\tNull load (generation only)" << endl;
|
||||
break;
|
||||
}
|
||||
cout << "\tIn Directory:\t\t" << szInDir << endl;
|
||||
cout << "\tStart From Customer:\t" << iStartFromCustomer << endl;
|
||||
cout << "\tCustomer Count:\t\t" << iCustomerCount << endl;
|
||||
cout << "\tTotal customers:\t" << iTotalCustomerCount << endl;
|
||||
cout << "\tLoad Unit:\t\t" << iLoadUnitSize << endl;
|
||||
cout << "\tScale Factor:\t\t" << iScaleFactor << endl;
|
||||
cout << "\tInitial Trade Days:\t" << iDaysOfInitialTrades << endl;
|
||||
cout << "\tCaching Enabled:\t" << (bGenerateUsingCache ? "true" : "false") << endl;
|
||||
cout << endl << endl;
|
||||
|
||||
// Know the load type => create the loader factory.
|
||||
//
|
||||
pLoaderFactory = CreateLoaderFactory(LoadType);
|
||||
|
||||
try {
|
||||
// Create a unique log name for this loader instance.
|
||||
// Simultaneous loader instances are to be run with
|
||||
// disjoint customer ranges, so use this fact to
|
||||
// construct a unique name.
|
||||
//
|
||||
char szLogFileName[64];
|
||||
|
||||
snprintf(&szLogFileName[0], sizeof(szLogFileName), "EGenLoaderFrom%" PRId64 "To%" PRId64 ".log",
|
||||
iStartFromCustomer, (iStartFromCustomer + iCustomerCount) - 1);
|
||||
|
||||
// Create log formatter and logger instance
|
||||
CLogFormatTab fmt;
|
||||
CEGenLogger logger(eDriverEGenLoader, 0, szLogFileName, &fmt);
|
||||
|
||||
// Set up data file manager for lazy load.
|
||||
const DataFileManager dfm(std::string(szInDir), iTotalCustomerCount, iTotalCustomerCount);
|
||||
|
||||
// Create the main class instance
|
||||
pGenerateAndLoad = new CGenerateAndLoad(dfm, iCustomerCount, iStartFromCustomer, iTotalCustomerCount,
|
||||
iLoadUnitSize, iScaleFactor, iDaysOfInitialTrades, pLoaderFactory,
|
||||
&logger, &Output, szInDir, bGenerateUsingCache);
|
||||
|
||||
// The generate and load phase starts here.
|
||||
//
|
||||
StartTime.Set();
|
||||
|
||||
// Generate static tables if appropriate.
|
||||
if ((bTableGenerationFlagNotSpecified && (iStartFromCustomer == iDefaultStartFromCustomer)) ||
|
||||
bGenerateFixedTables) {
|
||||
pGenerateAndLoad->GenerateAndLoadFixedTables();
|
||||
}
|
||||
|
||||
// Generate dynamic scaling tables if appropriate.
|
||||
if (bTableGenerationFlagNotSpecified || bGenerateScalingTables) {
|
||||
pGenerateAndLoad->GenerateAndLoadScalingTables();
|
||||
}
|
||||
// Generate dynamic trade tables if appropriate.
|
||||
if (bTableGenerationFlagNotSpecified || bGenerateGrowingTables) {
|
||||
pGenerateAndLoad->GenerateAndLoadGrowingTables();
|
||||
}
|
||||
|
||||
// The generate and load phase ends here.
|
||||
//
|
||||
EndTime.Set();
|
||||
|
||||
LoadTime.Set(0); // clear time
|
||||
LoadTime.Add(0, (int)((EndTime - StartTime) * MsPerSecond)); // add ms
|
||||
|
||||
cout << endl << "Generate and load time: " << LoadTime.ToStr(01) << endl << endl;
|
||||
|
||||
delete pGenerateAndLoad; // don't really need to do that, but just for
|
||||
// good style
|
||||
delete pLoaderFactory; // don't really need to do that, but just for
|
||||
// good style
|
||||
|
||||
} catch (CBaseErr &err) {
|
||||
cout << endl << "Error " << err.ErrorNum() << ": " << err.ErrorText();
|
||||
if (err.ErrorLoc()) {
|
||||
cout << " at " << err.ErrorLoc() << endl;
|
||||
} else {
|
||||
cout << endl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// operator new will throw std::bad_alloc exception if there is no
|
||||
// sufficient memory for the request.
|
||||
//
|
||||
catch (std::bad_alloc &) {
|
||||
cout << endl << endl << "*** Out of memory ***" << endl;
|
||||
return 2;
|
||||
} catch (std::exception &err) {
|
||||
cout << endl << endl << "Caught Exception: " << err.what() << endl;
|
||||
} catch (...) {
|
||||
cout << endl << endl << "Caught Unknown Exception" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
422
external/duckdb/third_party/tpce-tool/main/EGenLogFormatterTab.cpp
vendored
Normal file
422
external/duckdb/third_party/tpce-tool/main/EGenLogFormatterTab.cpp
vendored
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* 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
|
||||
* - Matt Emmerton
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: This file implements the methods for formatting
|
||||
* log entries in TSV or CSV format.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/EGenLogFormatterTab.h"
|
||||
#include "main/DriverTypes.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CE Transaction Settings
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CBrokerVolumeSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Broker Volume Parameters: NONE" << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CCustomerPositionSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Customer Position Parameters:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "By Cust ID: " << parms.dft.by_cust_id << "\t" << parms.cur.by_cust_id << "\t"
|
||||
<< (parms.state.by_cust_id ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "By Tax ID: " << parms.dft.by_tax_id << "\t" << parms.cur.by_tax_id << "\t"
|
||||
<< (parms.state.by_tax_id ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Get History: " << parms.dft.get_history << "\t" << parms.cur.get_history << "\t"
|
||||
<< (parms.state.get_history ? "YES" : "NO") << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CMarketWatchSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Market Watch Parameters:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "By Account ID: " << parms.dft.by_acct_id << "\t" << parms.cur.by_acct_id << "\t"
|
||||
<< (parms.state.by_acct_id ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "By Industry: " << parms.dft.by_industry << "\t" << parms.cur.by_industry << "\t"
|
||||
<< (parms.state.by_industry ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "By Watch List: " << parms.dft.by_watch_list << "\t" << parms.cur.by_watch_list
|
||||
<< "\t" << (parms.state.by_watch_list ? "YES" : "NO") << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CSecurityDetailSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Security Detail Parameters:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "LOB Access Pct: " << parms.dft.LOBAccessPercentage << "\t"
|
||||
<< parms.cur.LOBAccessPercentage << "\t" << (parms.state.LOBAccessPercentage ? "YES" : "NO") << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CTradeLookupSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Trade Lookup Parameters:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "Frame 1 Pct:" << parms.dft.do_frame1 << "\t" << parms.cur.do_frame1 << "\t"
|
||||
<< (parms.state.do_frame1 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 2 Pct:" << parms.dft.do_frame2 << "\t" << parms.cur.do_frame2 << "\t"
|
||||
<< (parms.state.do_frame2 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 3 Pct:" << parms.dft.do_frame3 << "\t" << parms.cur.do_frame3 << "\t"
|
||||
<< (parms.state.do_frame3 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 4 Pct:" << parms.dft.do_frame4 << "\t" << parms.cur.do_frame4 << "\t"
|
||||
<< (parms.state.do_frame4 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 1 MaxRows:" << parms.dft.MaxRowsFrame1 << "\t" << parms.cur.MaxRowsFrame1
|
||||
<< "\t" << (parms.state.MaxRowsFrame1 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 2 MaxRows:" << parms.dft.MaxRowsFrame2 << "\t" << parms.cur.MaxRowsFrame2
|
||||
<< "\t" << (parms.state.MaxRowsFrame2 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 3 MaxRows:" << parms.dft.MaxRowsFrame3 << "\t" << parms.cur.MaxRowsFrame3
|
||||
<< "\t" << (parms.state.MaxRowsFrame3 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 4 MaxRows:" << parms.dft.MaxRowsFrame4 << "\t" << parms.cur.MaxRowsFrame4
|
||||
<< "\t" << (parms.state.MaxRowsFrame4 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "BackOffFromEndTimeFrame2:" << parms.dft.BackOffFromEndTimeFrame2 << "\t"
|
||||
<< parms.cur.BackOffFromEndTimeFrame2 << "\t" << (parms.state.BackOffFromEndTimeFrame2 ? "YES" : "NO")
|
||||
<< endl;
|
||||
logmsg << left << setw(40) << "BackOffFromEndTimeFrame3:" << parms.dft.BackOffFromEndTimeFrame3 << "\t"
|
||||
<< parms.cur.BackOffFromEndTimeFrame3 << "\t" << (parms.state.BackOffFromEndTimeFrame3 ? "YES" : "NO")
|
||||
<< endl;
|
||||
logmsg << left << setw(40) << "BackOffFromEndTimeFrame4:" << parms.dft.BackOffFromEndTimeFrame4 << "\t"
|
||||
<< parms.cur.BackOffFromEndTimeFrame4 << "\t" << (parms.state.BackOffFromEndTimeFrame4 ? "YES" : "NO")
|
||||
<< endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CTradeOrderSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Trade Order Parameters:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "Market Trade Pct:" << parms.dft.market << "\t" << parms.cur.market << "\t"
|
||||
<< (parms.state.market ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Limit Trade Pct:" << parms.dft.limit << "\t" << parms.cur.limit << "\t"
|
||||
<< (parms.state.limit ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Stop Loss Pct:" << parms.dft.stop_loss << "\t" << parms.cur.stop_loss << "\t"
|
||||
<< (parms.state.stop_loss ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Security by Name Pct:" << parms.dft.security_by_name << "\t"
|
||||
<< parms.cur.security_by_name << "\t" << (parms.state.security_by_name ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Security by Symbol Pct:" << parms.dft.security_by_symbol << "\t"
|
||||
<< parms.cur.security_by_symbol << "\t" << (parms.state.security_by_symbol ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Buy Order Pct:" << parms.dft.buy_orders << "\t" << parms.cur.buy_orders << "\t"
|
||||
<< (parms.state.buy_orders ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Sell Order Pct:" << parms.dft.sell_orders << "\t" << parms.cur.sell_orders << "\t"
|
||||
<< (parms.state.sell_orders ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "LIFO Pct:" << parms.dft.lifo << "\t" << parms.cur.lifo << "\t"
|
||||
<< (parms.state.lifo ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Margin Trade Pct:" << parms.dft.type_is_margin << "\t" << parms.cur.type_is_margin
|
||||
<< "\t" << (parms.state.type_is_margin ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Executor as Owner Pct:" << parms.dft.exec_is_owner << "\t" << parms.cur.exec_is_owner
|
||||
<< "\t" << (parms.state.exec_is_owner ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Rollback Pct:" << parms.dft.rollback << "\t" << parms.cur.rollback << "\t"
|
||||
<< (parms.state.rollback ? "YES" : "NO") << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CTradeUpdateSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Trade Update Parameters:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "Frame 1 Pct:" << parms.dft.do_frame1 << "\t" << parms.cur.do_frame1 << "\t"
|
||||
<< (parms.state.do_frame1 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 2 Pct:" << parms.dft.do_frame2 << "\t" << parms.cur.do_frame2 << "\t"
|
||||
<< (parms.state.do_frame2 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 3 Pct:" << parms.dft.do_frame3 << "\t" << parms.cur.do_frame3 << "\t"
|
||||
<< (parms.state.do_frame3 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 1 MaxRows:" << parms.dft.MaxRowsFrame1 << "\t" << parms.cur.MaxRowsFrame1
|
||||
<< "\t" << (parms.state.MaxRowsFrame1 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 2 MaxRows:" << parms.dft.MaxRowsFrame2 << "\t" << parms.cur.MaxRowsFrame2
|
||||
<< "\t" << (parms.state.MaxRowsFrame2 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 3 MaxRows:" << parms.dft.MaxRowsFrame3 << "\t" << parms.cur.MaxRowsFrame3
|
||||
<< "\t" << (parms.state.MaxRowsFrame3 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 1 MaxRowsToUpdate:" << parms.dft.MaxRowsToUpdateFrame1 << "\t"
|
||||
<< parms.cur.MaxRowsToUpdateFrame1 << "\t" << (parms.state.MaxRowsToUpdateFrame1 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 2 MaxRowsToUpdate:" << parms.dft.MaxRowsToUpdateFrame2 << "\t"
|
||||
<< parms.cur.MaxRowsToUpdateFrame2 << "\t" << (parms.state.MaxRowsToUpdateFrame2 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Frame 3 MaxRowsToUpdate:" << parms.dft.MaxRowsToUpdateFrame3 << "\t"
|
||||
<< parms.cur.MaxRowsToUpdateFrame3 << "\t" << (parms.state.MaxRowsToUpdateFrame3 ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "BackOffFromEndTimeFrame2:" << parms.dft.BackOffFromEndTimeFrame2 << "\t"
|
||||
<< parms.cur.BackOffFromEndTimeFrame2 << "\t" << (parms.state.BackOffFromEndTimeFrame2 ? "YES" : "NO")
|
||||
<< endl;
|
||||
logmsg << left << setw(40) << "BackOffFromEndTimeFrame3:" << parms.dft.BackOffFromEndTimeFrame3 << "\t"
|
||||
<< parms.cur.BackOffFromEndTimeFrame3 << "\t" << (parms.state.BackOffFromEndTimeFrame3 ? "YES" : "NO")
|
||||
<< endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CE Transaction Mix Settings
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CTxnMixGeneratorSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Transaction Mixes:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "Broker Volume: " << parms.dft.BrokerVolumeMixLevel << "\t"
|
||||
<< parms.cur.BrokerVolumeMixLevel << "\t" << (parms.state.BrokerVolumeMixLevel ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Customer Position: " << parms.dft.CustomerPositionMixLevel << "\t"
|
||||
<< parms.cur.CustomerPositionMixLevel << "\t" << (parms.state.CustomerPositionMixLevel ? "YES" : "NO")
|
||||
<< endl;
|
||||
logmsg << left << setw(40) << "Market Watch: " << parms.dft.MarketWatchMixLevel << "\t"
|
||||
<< parms.cur.MarketWatchMixLevel << "\t" << (parms.state.MarketWatchMixLevel ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Security Detail: " << parms.dft.SecurityDetailMixLevel << "\t"
|
||||
<< parms.cur.SecurityDetailMixLevel << "\t" << (parms.state.SecurityDetailMixLevel ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Trade Lookup: " << parms.dft.TradeLookupMixLevel << "\t"
|
||||
<< parms.cur.TradeLookupMixLevel << "\t" << (parms.state.TradeLookupMixLevel ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Trade Order: " << parms.dft.TradeOrderMixLevel << "\t"
|
||||
<< parms.cur.TradeOrderMixLevel << "\t" << (parms.state.TradeOrderMixLevel ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Trade Status: " << parms.dft.TradeStatusMixLevel << "\t"
|
||||
<< parms.cur.TradeStatusMixLevel << "\t" << (parms.state.TradeStatusMixLevel ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Trade Update: " << parms.dft.TradeUpdateMixLevel << "\t"
|
||||
<< parms.cur.TradeUpdateMixLevel << "\t" << (parms.state.TradeUpdateMixLevel ? "YES" : "NO") << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Loader Settings
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CLoaderSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Loader Settings:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "Configured Customers:" << parms.dft.iConfiguredCustomerCount << "\t"
|
||||
<< parms.cur.iConfiguredCustomerCount << endl;
|
||||
if (parms.cur.iConfiguredCustomerCount != parms.cur.iActiveCustomerCount) {
|
||||
logmsg << left << setw(40) << "Active Customers:" << parms.dft.iActiveCustomerCount << "\t"
|
||||
<< parms.cur.iActiveCustomerCount << endl;
|
||||
}
|
||||
logmsg << left << setw(40) << "Starting Customer:" << parms.dft.iStartingCustomer << "\t"
|
||||
<< parms.cur.iStartingCustomer << endl;
|
||||
logmsg << left << setw(40) << "Customer Count:" << parms.dft.iCustomerCount << "\t" << parms.cur.iCustomerCount
|
||||
<< endl;
|
||||
logmsg << left << setw(40) << "Scale Factor:" << parms.dft.iScaleFactor << "\t" << parms.cur.iScaleFactor << "\t"
|
||||
<< (parms.state.iScaleFactor ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Days of Initial Trades:" << parms.dft.iDaysOfInitialTrades << "\t"
|
||||
<< parms.cur.iDaysOfInitialTrades << "\t" << (parms.state.iDaysOfInitialTrades ? "YES" : "NO") << endl;
|
||||
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Driver Settings
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CDriverGlobalSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Driver Global Settings:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "Configured Customers:" << parms.dft.iConfiguredCustomerCount << "\t"
|
||||
<< parms.cur.iConfiguredCustomerCount << endl;
|
||||
logmsg << left << setw(40) << "Active Customers:" << parms.dft.iActiveCustomerCount << "\t"
|
||||
<< parms.cur.iActiveCustomerCount << endl;
|
||||
logmsg << left << setw(40) << "Scale Factor:" << parms.dft.iScaleFactor << "\t" << parms.cur.iScaleFactor << "\t"
|
||||
<< (parms.state.iScaleFactor ? "YES" : "NO") << endl;
|
||||
logmsg << left << setw(40) << "Days of Initial Trades:" << parms.dft.iDaysOfInitialTrades << "\t"
|
||||
<< parms.cur.iDaysOfInitialTrades << "\t" << (parms.state.iDaysOfInitialTrades ? "YES" : "NO") << endl;
|
||||
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CDriverCESettings &parms) {
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Driver CE Settings:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Value" << endl;
|
||||
logmsg << left << setw(40) << "Unique ID:" << parms.cur.UniqueId << endl;
|
||||
logmsg << left << setw(40) << "Txn Mix RNGSeed:" << parms.cur.TxnMixRNGSeed << endl;
|
||||
logmsg << left << setw(40) << "Txn Input RNGSeed:" << parms.cur.TxnInputRNGSeed << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CDriverCEPartitionSettings &parms) {
|
||||
// Compare against defaults
|
||||
parms.CheckDefaults();
|
||||
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Driver CE Partition Settings:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Default"
|
||||
<< "\t"
|
||||
<< "Current"
|
||||
<< "\t"
|
||||
<< "Default?" << endl;
|
||||
logmsg << left << setw(40) << "Partition Starting Customer ID:" << parms.dft.iMyStartingCustomerId << "\t"
|
||||
<< parms.cur.iMyStartingCustomerId << endl;
|
||||
logmsg << left << setw(40) << "Partition Customer Count:" << parms.dft.iMyCustomerCount << "\t"
|
||||
<< parms.cur.iMyCustomerCount << endl;
|
||||
logmsg << left << setw(40) << "Partition Percent:" << parms.dft.iPartitionPercent << "\t"
|
||||
<< parms.cur.iPartitionPercent << "\t" << (parms.state.iPartitionPercent ? "YES" : "NO") << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CDriverMEESettings &parms) {
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Driver MEE Settings:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Value" << endl;
|
||||
logmsg << left << setw(40) << "Unique ID:" << parms.cur.UniqueId << endl;
|
||||
logmsg << left << setw(40) << "Ticker Tape RNGSeed:" << parms.cur.TickerTapeRNGSeed << endl;
|
||||
logmsg << left << setw(40) << "Trading Floor RNGSeed:" << parms.cur.TradingFloorRNGSeed << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
|
||||
string CLogFormatTab::GetLogOutput(CDriverDMSettings &parms) {
|
||||
// Construct Log String
|
||||
logmsg.str(emptyString);
|
||||
logmsg << "Driver DM Settings:" << endl;
|
||||
logmsg << left << setw(40) << "Parameter"
|
||||
<< "Value" << endl;
|
||||
logmsg << left << setw(40) << "Unique ID:" << parms.cur.UniqueId << endl;
|
||||
logmsg << left << setw(40) << "RNGSeed:" << parms.cur.RNGSeed << endl;
|
||||
|
||||
// Send String to Logger
|
||||
return (logmsg.str());
|
||||
}
|
||||
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);
|
||||
}
|
||||
80
external/duckdb/third_party/tpce-tool/main/ExchangeTable.cpp
vendored
Normal file
80
external/duckdb/third_party/tpce-tool/main/ExchangeTable.cpp
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/ExchangeTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "utilities/MiscConsts.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
void CExchangeTable::ComputeNumSecurities(TIdent iCustomerCount) {
|
||||
// There are 685 securities per Load Unit. The flat_in/Security.txt contains
|
||||
// 10 LUs worth of securities. This array is a pre-computation of the
|
||||
// cumulative number of securities each excahnge has in the first 10 LUs.
|
||||
const int iSecurityCounts[4][11] = {{0, 153, 307, 491, 688, 859, 1028, 1203, 1360, 1532, 1704},
|
||||
{0, 173, 344, 498, 658, 848, 1006, 1191, 1402, 1572, 1749},
|
||||
{0, 189, 360, 534, 714, 875, 1023, 1174, 1342, 1507, 1666},
|
||||
{0, 170, 359, 532, 680, 843, 1053, 1227, 1376, 1554, 1731}};
|
||||
INT32 numLU = static_cast<INT32>(iCustomerCount / 1000);
|
||||
INT32 numLU_Tens = numLU / 10;
|
||||
INT32 numLU_Ones = numLU % 10;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
securityCount[i] = iSecurityCounts[i][10] * numLU_Tens + iSecurityCounts[i][numLU_Ones];
|
||||
}
|
||||
}
|
||||
|
||||
CExchangeTable::CExchangeTable(const ExchangeDataFile_t &dataFile, TIdent configuredCustomers)
|
||||
: FixedTable<ExchangeDataFile_t, EXCHANGE_ROW>(dataFile) {
|
||||
ComputeNumSecurities(configuredCustomers);
|
||||
}
|
||||
|
||||
CExchangeTable::~CExchangeTable() {
|
||||
}
|
||||
|
||||
void CExchangeTable::LoadTableRow() {
|
||||
const ExchangeDataFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
tableRow.EX_AD_ID = dataRecord.EX_AD_ID() + iTIdentShift;
|
||||
tableRow.EX_CLOSE = dataRecord.EX_CLOSE();
|
||||
strncpy(tableRow.EX_DESC, dataRecord.EX_DESC_CSTR(), sizeof(tableRow.EX_DESC));
|
||||
strncpy(tableRow.EX_ID, dataRecord.EX_ID_CSTR(), sizeof(tableRow.EX_ID));
|
||||
strncpy(tableRow.EX_NAME, dataRecord.EX_NAME_CSTR(), sizeof(tableRow.EX_NAME));
|
||||
tableRow.EX_NUM_SYMB = securityCount[recordIdx];
|
||||
tableRow.EX_OPEN = dataRecord.EX_OPEN();
|
||||
}
|
||||
76
external/duckdb/third_party/tpce-tool/main/FlatFileLoader.cpp
vendored
Normal file
76
external/duckdb/third_party/tpce-tool/main/FlatFileLoader.cpp
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/FlatFileLoad_stdafx.h"
|
||||
|
||||
#include "main/TableTypes.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
namespace TPCE {
|
||||
// Explicit Instantiation to generate code
|
||||
// template class CFlatFileLoader<ACCOUNT_PERMISSION_ROW>;
|
||||
// template class CFlatFileLoader<ADDRESS_ROW>;
|
||||
// template class CFlatFileLoader<BROKER_ROW>;
|
||||
// template class CFlatFileLoader<CASH_TRANSACTION_ROW>;
|
||||
// template class CFlatFileLoader<ChargeTableRecord_t>;
|
||||
// template class CFlatFileLoader<CommissionRateTableRecord_t>;
|
||||
// template class CFlatFileLoader<COMPANY_ROW>;
|
||||
// template class CFlatFileLoader<COMPANY_COMPETITOR_ROW>;
|
||||
// template class CFlatFileLoader<CUSTOMER_ROW>;
|
||||
// template class CFlatFileLoader<CUSTOMER_ACCOUNT_ROW>;
|
||||
// template class CFlatFileLoader<CUSTOMER_TAXRATE_ROW>;
|
||||
// template class CFlatFileLoader<DAILY_MARKET_ROW>;
|
||||
// template class CFlatFileLoader<FINANCIAL_ROW>;
|
||||
// template class CFlatFileLoader<HOLDING_ROW>;
|
||||
// template class CFlatFileLoader<HOLDING_HISTORY_ROW>;
|
||||
// template class CFlatFileLoader<HOLDING_SUMMARY_ROW>;
|
||||
// template class CFlatFileLoader<IndustryTableRecord_t>;
|
||||
// template class CFlatFileLoader<LAST_TRADE_ROW>;
|
||||
// template class CFlatFileLoader<NEWS_ITEM_ROW>;
|
||||
// template class CFlatFileLoader<NEWS_XREF_ROW>;
|
||||
// template class CFlatFileLoader<SectorTableRecord_t>;
|
||||
// template class CFlatFileLoader<SECURITY_ROW>;
|
||||
// template class CFlatFileLoader<SETTLEMENT_ROW>;
|
||||
// template class CFlatFileLoader<StatusTypeTableRecord_t>;
|
||||
// template class CFlatFileLoader<TaxRateTableRecord_t>;
|
||||
// template class CFlatFileLoader<TRADE_ROW>;
|
||||
// template class CFlatFileLoader<TRADE_HISTORY_ROW>;
|
||||
// template class CFlatFileLoader<TRADE_REQUEST_ROW>;
|
||||
// template class CFlatFileLoader<TradeTypeTableRecord_t>;
|
||||
// template class CFlatFileLoader<WATCH_ITEM_ROW>;
|
||||
// template class CFlatFileLoader<WATCH_LIST_ROW>;
|
||||
} // namespace TPCE
|
||||
56
external/duckdb/third_party/tpce-tool/main/IndustryTable.cpp
vendored
Normal file
56
external/duckdb/third_party/tpce-tool/main/IndustryTable.cpp
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/IndustryTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CIndustryTable::CIndustryTable(const IndustryDataFile_t &dataFile)
|
||||
: FixedTable<IndustryDataFile_t, INDUSTRY_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
CIndustryTable::~CIndustryTable() {
|
||||
}
|
||||
|
||||
void CIndustryTable::LoadTableRow() {
|
||||
const IndustryDataFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
strncpy(tableRow.IN_ID, dataRecord.IN_ID_CSTR(), sizeof(tableRow.IN_ID));
|
||||
strncpy(tableRow.IN_NAME, dataRecord.IN_NAME_CSTR(), sizeof(tableRow.IN_NAME));
|
||||
strncpy(tableRow.IN_SC_ID, dataRecord.IN_SC_ID_CSTR(), sizeof(tableRow.IN_SC_ID));
|
||||
}
|
||||
181
external/duckdb/third_party/tpce-tool/main/MEE.cpp
vendored
Normal file
181
external/duckdb/third_party/tpce-tool/main/MEE.cpp
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson, Matt Emmerton
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of the MEE class.
|
||||
* See MEE.h for a description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/MEE.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
// Automatically generate unique RNG seeds.
|
||||
// The CRandom class uses an unsigned 64-bit value for the seed.
|
||||
// This routine automatically generates two unique seeds. One is used for
|
||||
// the TxnInput generator RNG, and the other is for the TxnMixGenerator RNG.
|
||||
// The 64 bits are used as follows.
|
||||
//
|
||||
// Bits 0 - 31 Caller provided unique unsigned 32-bit id.
|
||||
// Bit 32 0 for TxnInputGenerator, 1 for TxnMixGenerator
|
||||
// Bits 33 - 43 Number of days since the base time. The base time
|
||||
// is set to be January 1 of the most recent year that is
|
||||
// a multiple of 5. This allows enough space for the last
|
||||
// field, and it makes the algorithm "timeless" by resetting
|
||||
// the generated values every 5 years.
|
||||
// Bits 44 - 63 Current time of day measured in 1/10's of a second.
|
||||
//
|
||||
void CMEE::AutoSetRNGSeeds(UINT32 UniqueId) {
|
||||
CDateTime Now;
|
||||
INT32 BaseYear;
|
||||
INT32 Tmp1, Tmp2;
|
||||
|
||||
Now.GetYMD(&BaseYear, &Tmp1, &Tmp2);
|
||||
|
||||
// Set the base year to be the most recent year that was a multiple of 5.
|
||||
BaseYear -= (BaseYear % 5);
|
||||
CDateTime Base(BaseYear, 1, 1); // January 1st in the BaseYear
|
||||
|
||||
// Initialize the seed with the current time of day measured in 1/10's of a
|
||||
// second. This will use up to 20 bits.
|
||||
RNGSEED Seed;
|
||||
Seed = Now.MSec() / 100;
|
||||
|
||||
// Now add in the number of days since the base time.
|
||||
// The number of days in the 5 year period requires 11 bits.
|
||||
// So shift up by that much to make room in the "lower" bits.
|
||||
Seed <<= 11;
|
||||
Seed += (RNGSEED)((INT64)Now.DayNo() - (INT64)Base.DayNo());
|
||||
|
||||
// So far, we've used up 31 bits.
|
||||
// Save the "last" bit of the "upper" 32 for the RNG id.
|
||||
// In addition, make room for the caller's 32-bit unique id.
|
||||
// So shift a total of 33 bits.
|
||||
Seed <<= 33;
|
||||
|
||||
// Now the "upper" 32-bits have been set with a value for RNG 0.
|
||||
// Add in the sponsor's unique id for the "lower" 32-bits.
|
||||
Seed += UniqueId;
|
||||
|
||||
// Set the Ticker Tape RNG to the unique seed.
|
||||
m_TickerTape.SetRNGSeed(Seed);
|
||||
m_DriverMEESettings.cur.TickerTapeRNGSeed = Seed;
|
||||
|
||||
// Set the RNG Id to 1 for the Trading Floor.
|
||||
Seed |= UINT64_CONST(0x0000000100000000);
|
||||
m_TradingFloor.SetRNGSeed(Seed);
|
||||
m_DriverMEESettings.cur.TradingFloorRNGSeed = Seed;
|
||||
}
|
||||
|
||||
// Constructor - automatic RNG seed generation
|
||||
CMEE::CMEE(INT32 TradingTimeSoFar, CMEESUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm,
|
||||
UINT32 UniqueId)
|
||||
: m_DriverMEESettings(UniqueId, 0, 0, 0), m_pSUT(pSUT), m_pLogger(pLogger),
|
||||
m_PriceBoard(TradingTimeSoFar, &m_BaseTime, &m_CurrentTime, dfm),
|
||||
m_TickerTape(pSUT, &m_PriceBoard, &m_BaseTime, &m_CurrentTime, dfm),
|
||||
m_TradingFloor(pSUT, &m_PriceBoard, &m_TickerTape, &m_BaseTime, &m_CurrentTime), m_MEELock() {
|
||||
m_pLogger->SendToLogger("MEE object constructed using c'tor 1 (valid for publication: YES).");
|
||||
|
||||
AutoSetRNGSeeds(UniqueId);
|
||||
|
||||
m_pLogger->SendToLogger(m_DriverMEESettings);
|
||||
}
|
||||
|
||||
// Constructor - RNG seed provided
|
||||
CMEE::CMEE(INT32 TradingTimeSoFar, CMEESUTInterface *pSUT, CBaseLogger *pLogger, const DataFileManager &dfm,
|
||||
UINT32 UniqueId, RNGSEED TickerTapeRNGSeed, RNGSEED TradingFloorRNGSeed)
|
||||
: m_DriverMEESettings(UniqueId, 0, TickerTapeRNGSeed, TradingFloorRNGSeed), m_pSUT(pSUT), m_pLogger(pLogger),
|
||||
m_PriceBoard(TradingTimeSoFar, &m_BaseTime, &m_CurrentTime, dfm),
|
||||
m_TickerTape(pSUT, &m_PriceBoard, &m_BaseTime, &m_CurrentTime, TickerTapeRNGSeed, dfm),
|
||||
m_TradingFloor(pSUT, &m_PriceBoard, &m_TickerTape, &m_BaseTime, &m_CurrentTime, TradingFloorRNGSeed),
|
||||
m_MEELock() {
|
||||
m_pLogger->SendToLogger("MEE object constructed using c'tor 2 (valid for publication: NO).");
|
||||
m_pLogger->SendToLogger(m_DriverMEESettings);
|
||||
}
|
||||
|
||||
CMEE::~CMEE(void) {
|
||||
m_pLogger->SendToLogger("MEE object destroyed.");
|
||||
}
|
||||
|
||||
RNGSEED CMEE::GetTickerTapeRNGSeed(void) {
|
||||
return (m_TickerTape.GetRNGSeed());
|
||||
}
|
||||
|
||||
RNGSEED CMEE::GetTradingFloorRNGSeed(void) {
|
||||
return (m_TradingFloor.GetRNGSeed());
|
||||
}
|
||||
|
||||
void CMEE::SetBaseTime(void) {
|
||||
m_MEELock.lock();
|
||||
m_BaseTime.Set();
|
||||
m_MEELock.unlock();
|
||||
}
|
||||
|
||||
bool CMEE::DisableTickerTape(void) {
|
||||
bool Result;
|
||||
m_MEELock.lock();
|
||||
Result = m_TickerTape.DisableTicker();
|
||||
m_MEELock.unlock();
|
||||
return (Result);
|
||||
}
|
||||
|
||||
bool CMEE::EnableTickerTape(void) {
|
||||
bool Result;
|
||||
m_MEELock.lock();
|
||||
Result = m_TickerTape.EnableTicker();
|
||||
m_MEELock.unlock();
|
||||
return (Result);
|
||||
}
|
||||
|
||||
INT32 CMEE::GenerateTradeResult(void) {
|
||||
INT32 NextTime;
|
||||
|
||||
m_MEELock.lock();
|
||||
m_CurrentTime.Set();
|
||||
NextTime = m_TradingFloor.GenerateTradeResult();
|
||||
m_MEELock.unlock();
|
||||
return (NextTime);
|
||||
}
|
||||
|
||||
INT32 CMEE::SubmitTradeRequest(PTradeRequest pTradeRequest) {
|
||||
INT32 NextTime;
|
||||
|
||||
m_MEELock.lock();
|
||||
m_CurrentTime.Set();
|
||||
NextTime = m_TradingFloor.SubmitTradeRequest(pTradeRequest);
|
||||
m_MEELock.unlock();
|
||||
return (NextTime);
|
||||
}
|
||||
112
external/duckdb/third_party/tpce-tool/main/MEEPriceBoard.cpp
vendored
Normal file
112
external/duckdb/third_party/tpce-tool/main/MEEPriceBoard.cpp
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implemenation of the MEEPriceBoard class.
|
||||
* See MEEPriceBoad.h for a description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/MEEPriceBoard.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CMEEPriceBoard::CMEEPriceBoard(INT32 TradingTimeSoFar, CDateTime *pBaseTime, CDateTime *pCurrentTime,
|
||||
const DataFileManager &dfm)
|
||||
: m_fMeanInTheMoneySubmissionDelay(1.0), m_Security(), m_SecurityFile(dfm.SecurityFile()),
|
||||
m_iNumberOfSecurities(0) {
|
||||
// Number of securities is based on "active" customers, as per sub-committee
|
||||
// decision to have a scaled-down database look as much as possible as the
|
||||
// smaller database.
|
||||
|
||||
// Note that this decision will ensure that some percentage of Trade-Order
|
||||
// transactions will *not* be subject to lock contention when accessing the
|
||||
// LAST_TRADE table, since they are "outside" of the active range that is
|
||||
// updated by the MEE via the Market-Feed transaction. This may provide an
|
||||
// incentive for sponsors to over-build and under-scale at run-time, to the
|
||||
// detriment of the benchmark. If this is the case, then we should require
|
||||
// the MEE to run using "configured" securities.
|
||||
|
||||
m_iNumberOfSecurities = m_SecurityFile.GetActiveSecurityCount();
|
||||
m_Security.Init(TradingTimeSoFar, pBaseTime, pCurrentTime, m_fMeanInTheMoneySubmissionDelay);
|
||||
m_SecurityFile.LoadSymbolToIdMap();
|
||||
}
|
||||
|
||||
CMEEPriceBoard::~CMEEPriceBoard(void) {
|
||||
}
|
||||
|
||||
void CMEEPriceBoard::GetSymbol(TIdent SecurityIndex,
|
||||
char *szOutput, // output buffer
|
||||
size_t iOutputLen) // size of the output buffer (including null));
|
||||
{
|
||||
return (m_SecurityFile.CreateSymbol(SecurityIndex, szOutput, iOutputLen));
|
||||
}
|
||||
|
||||
CMoney CMEEPriceBoard::GetMinPrice() {
|
||||
return (m_Security.GetMinPrice());
|
||||
}
|
||||
|
||||
CMoney CMEEPriceBoard::GetMaxPrice() {
|
||||
return (m_Security.GetMaxPrice());
|
||||
}
|
||||
|
||||
CMoney CMEEPriceBoard::GetCurrentPrice(TIdent SecurityIndex) {
|
||||
return (m_Security.GetCurrentPrice(SecurityIndex));
|
||||
}
|
||||
|
||||
CMoney CMEEPriceBoard::GetCurrentPrice(char *pSecuritySymbol) {
|
||||
return (m_Security.GetCurrentPrice(m_SecurityFile.GetIndex(pSecuritySymbol)));
|
||||
}
|
||||
|
||||
CMoney CMEEPriceBoard::CalculatePrice(char *pSecuritySymbol, double fTime) {
|
||||
return (m_Security.CalculatePrice(m_SecurityFile.GetIndex(pSecuritySymbol), fTime));
|
||||
}
|
||||
|
||||
double CMEEPriceBoard::GetSubmissionTime(char *pSecuritySymbol, double fPendingTime, CMoney fLimitPrice,
|
||||
eTradeTypeID TradeType) {
|
||||
return (
|
||||
m_Security.GetSubmissionTime(m_SecurityFile.GetIndex(pSecuritySymbol), fPendingTime, fLimitPrice, TradeType));
|
||||
}
|
||||
|
||||
double CMEEPriceBoard::GetSubmissionTime(TIdent SecurityIndex, double fPendingTime, CMoney fLimitPrice,
|
||||
eTradeTypeID TradeType) {
|
||||
return (m_Security.GetSubmissionTime(SecurityIndex, fPendingTime, fLimitPrice, TradeType));
|
||||
}
|
||||
|
||||
double CMEEPriceBoard::GetCompletionTime(TIdent SecurityIndex, double fSubmissionTime,
|
||||
CMoney *pCompletionPrice // output parameter
|
||||
) {
|
||||
return (m_Security.GetCompletionTime(SecurityIndex, fSubmissionTime, pCompletionPrice));
|
||||
}
|
||||
351
external/duckdb/third_party/tpce-tool/main/MEESecurity.cpp
vendored
Normal file
351
external/duckdb/third_party/tpce-tool/main/MEESecurity.cpp
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* 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
|
||||
* - Sergey Vasilevskiy, Doug Johnson
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of the MEESecurity class.
|
||||
* See MEESecurity.h for a description.
|
||||
******************************************************************************/
|
||||
|
||||
#include <cmath>
|
||||
#include "main/MEESecurity.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
// Period of security price change (in seconds)
|
||||
// e.g. when the price will repeat.
|
||||
//
|
||||
const int iSecPricePeriod = 900; // 15 minutes
|
||||
|
||||
// Mean delay between Submission and Completion times
|
||||
//
|
||||
const double fMeanCompletionTimeDelay = 1.0;
|
||||
|
||||
// Delay added to the clipped MEE Completion delay
|
||||
// to simulate SUT-to-MEE and MEE-to-SUT processing delays.
|
||||
//
|
||||
const double fCompletionSUTDelay = 1.0; // seconds
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
* Initializes the class using RNG and constants.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* not applicable.
|
||||
*/
|
||||
CMEESecurity::CMEESecurity()
|
||||
: m_rnd(RNGSeedBaseMEESecurity), m_fRangeLow(fMinSecPrice), m_fRangeHigh(fMaxSecPrice),
|
||||
m_fRange(fMaxSecPrice - fMinSecPrice), m_iPeriod(iSecPricePeriod), m_TradingTimeSoFar(0), m_pBaseTime(NULL),
|
||||
m_pCurrentTime(NULL) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize before the first use.
|
||||
* Separated from constructor in order to have default (no-parameters)
|
||||
* constructor.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN Index - unique security index to
|
||||
* generate a unique starting price IN TradeTimeSoFar - point
|
||||
* where we last left off on the price curve IN pBaseTime - wall clock time
|
||||
* corresponding to the initial time for all securities IN pCurrentTime -
|
||||
* current time for the security (determines current price) IN
|
||||
* fMeanInTheMoneySubmissionDelay - Mean delay between Pending and Submission
|
||||
* times for an immediatelly triggered (in-the-money) limit order.
|
||||
*
|
||||
* RETURNS:
|
||||
* none
|
||||
*/
|
||||
void CMEESecurity::Init(INT32 TradingTimeSoFar, // for picking up where we last
|
||||
// left off on the price curve
|
||||
CDateTime *pBaseTime, CDateTime *pCurrentTime,
|
||||
|
||||
// Mean delay between Pending and Submission times
|
||||
// for an immediatelly triggered (in-the-money) limit
|
||||
// order.
|
||||
//
|
||||
// The actual delay is randomly calculated in the range
|
||||
// [0.5 * Mean .. 1.5 * Mean]
|
||||
//
|
||||
double fMeanInTheMoneySubmissionDelay) {
|
||||
m_TradingTimeSoFar = TradingTimeSoFar;
|
||||
m_pBaseTime = pBaseTime;
|
||||
m_pCurrentTime = pCurrentTime;
|
||||
|
||||
m_fMeanInTheMoneySubmissionDelay = fMeanInTheMoneySubmissionDelay;
|
||||
|
||||
// Reset the RNG seed so that loading in multiple EGenLoader instances
|
||||
// results in the same database as running just one EGenLoader.
|
||||
//
|
||||
m_rnd.SetSeed(RNGSeedBaseMEESecurity);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the "unique" starting offset
|
||||
* in the price curve based on the security ID (0-based)
|
||||
* 0 corresponds to m_fRangeLow price,
|
||||
* m_fPeriod/2 corresponds to m_fRangeHigh price,
|
||||
* m_fPeriod corresponds again to m_fRangeLow price
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN SecurityIndex - unique security index to generate a unique
|
||||
* starting price
|
||||
*
|
||||
* RETURNS:
|
||||
* time from which to calculate initial price
|
||||
*/
|
||||
inline double CMEESecurity::InitialTime(TIdent SecurityIndex) {
|
||||
INT32 MsPerPeriod = iSecPricePeriod * MsPerSecond;
|
||||
TIdent SecurityFactor = SecurityIndex * 556237 + 253791;
|
||||
TIdent TradingFactor = (TIdent)m_TradingTimeSoFar * MsPerSecond; // Cast to avoid truncation
|
||||
|
||||
return (((TradingFactor + SecurityFactor) % MsPerPeriod) / MsPerSecondDivisor);
|
||||
}
|
||||
|
||||
/*
|
||||
* Negative exponential distribution.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN fMean - mean value of the distribution
|
||||
*
|
||||
* RETURNS:
|
||||
* random value according to the negative
|
||||
* exponential distribution with the given mean.
|
||||
*/
|
||||
inline double CMEESecurity::NegExp(double fMean) {
|
||||
return RoundToNearestNsec(m_rnd.RndDoubleNegExp(fMean));
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate current price for the security identified by its index (0-based).
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN SecurityIndex - unique identifier for the security.
|
||||
*
|
||||
* RETURNS:
|
||||
* price at this point in time given with integer number of cents.
|
||||
*/
|
||||
CMoney CMEESecurity::GetCurrentPrice(TIdent SecurityIndex) {
|
||||
return (CalculatePrice(SecurityIndex, *m_pCurrentTime - *m_pBaseTime));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return minimum price on the price curve for any security.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* minimum price given with integer number of cents.
|
||||
*/
|
||||
CMoney CMEESecurity::GetMinPrice(void) {
|
||||
return (m_fRangeLow);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return maximum price on the price curve for any security.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* none.
|
||||
*
|
||||
* RETURNS:
|
||||
* maximum price given with integer number of cents.
|
||||
*/
|
||||
CMoney CMEESecurity::GetMaxPrice(void) {
|
||||
return (m_fRangeHigh);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate price at a certain point in time.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN SecurityIndex - unique security index to generate a unique
|
||||
* starting price IN fTime - seconds from initial time
|
||||
*
|
||||
* RETURNS:
|
||||
* price according to the triangular function
|
||||
* that will be achived at the given time
|
||||
*/
|
||||
CMoney CMEESecurity::CalculatePrice(TIdent SecurityIndex, double fTime) {
|
||||
double fPeriodTime = (fTime + InitialTime(SecurityIndex)) / (double)m_iPeriod;
|
||||
double fTimeWithinPeriod = (fPeriodTime - (int)fPeriodTime) * (double)m_iPeriod;
|
||||
|
||||
double fPricePosition; // 0..1 corresponding to m_fRangeLow..m_fRangeHigh
|
||||
CMoney PriceCents;
|
||||
|
||||
if (fTimeWithinPeriod < m_iPeriod / 2) {
|
||||
fPricePosition = fTimeWithinPeriod / (m_iPeriod / 2);
|
||||
} else {
|
||||
fPricePosition = (m_iPeriod - fTimeWithinPeriod) / (m_iPeriod / 2);
|
||||
}
|
||||
|
||||
PriceCents = m_fRangeLow + m_fRange * fPricePosition;
|
||||
|
||||
return PriceCents;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate time required to move between certain prices
|
||||
* with certain initial direction of price change.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN fStartPrice - price at the start of the time interval
|
||||
* IN fEndPrice - price at the end of the time interval
|
||||
* IN iStartDirection - direction (up or down) on the price curve at
|
||||
* the start of the time interval
|
||||
*
|
||||
* RETURNS:
|
||||
* seconds required to move from the start price to the end price
|
||||
*/
|
||||
double CMEESecurity::CalculateTime(CMoney fStartPrice, CMoney fEndPrice, int iStartDirection) {
|
||||
int iHalfPeriod = m_iPeriod / 2;
|
||||
|
||||
// Distance on the price curve from StartPrice to EndPrice (in dollars)
|
||||
//
|
||||
CMoney fDistance;
|
||||
|
||||
// Amount of time (in seconds) needed to move $1 on the price curve.
|
||||
// In half a period the price moves over the entire price range.
|
||||
//
|
||||
double fSpeed = iHalfPeriod / m_fRange.DollarAmount();
|
||||
|
||||
if (fEndPrice > fStartPrice) {
|
||||
if (iStartDirection > 0) {
|
||||
fDistance = fEndPrice - fStartPrice;
|
||||
} else {
|
||||
fDistance = (fStartPrice - m_fRangeLow) + (fEndPrice - m_fRangeLow);
|
||||
}
|
||||
} else {
|
||||
if (iStartDirection > 0) {
|
||||
fDistance = (m_fRangeHigh - fStartPrice) + (m_fRangeHigh - fEndPrice);
|
||||
} else {
|
||||
fDistance = fStartPrice - fEndPrice;
|
||||
}
|
||||
}
|
||||
|
||||
return fDistance.DollarAmount() * fSpeed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate triggering time for limit orders.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN SecurityIndex - unique security index to generate a unique
|
||||
* starting price IN fPendingTime - pending time of the order, in seconds
|
||||
* from time 0 IN fLimitPrice - limit price of the order IN TradeType -
|
||||
* order trade type
|
||||
*
|
||||
* RETURNS:
|
||||
* the expected submission time
|
||||
*/
|
||||
double CMEESecurity::GetSubmissionTime(TIdent SecurityIndex,
|
||||
double fPendingTime, // in seconds from time 0
|
||||
CMoney fLimitPrice, eTradeTypeID TradeType) {
|
||||
CMoney fPriceAtPendingTime = CalculatePrice(SecurityIndex, fPendingTime);
|
||||
|
||||
int iDirectionAtPendingTime;
|
||||
|
||||
double fSubmissionTimeFromPending; // Submission - Pending time difference
|
||||
|
||||
// Check if the order is already in the money
|
||||
// e.g. if the current price is less than the buy price
|
||||
// or the current price is more than the sell price.
|
||||
//
|
||||
if (((TradeType == eLimitBuy || TradeType == eStopLoss) && fPriceAtPendingTime <= fLimitPrice) ||
|
||||
((TradeType == eLimitSell) && fPriceAtPendingTime >= fLimitPrice)) {
|
||||
// Order is in-the-money. Trigger immediatelly.
|
||||
//
|
||||
fSubmissionTimeFromPending = m_rnd.RndDoubleIncrRange(0.5 * m_fMeanInTheMoneySubmissionDelay,
|
||||
1.5 * m_fMeanInTheMoneySubmissionDelay, 0.001);
|
||||
} else {
|
||||
if ((int)(fPendingTime + InitialTime(SecurityIndex)) % m_iPeriod < m_iPeriod / 2) {
|
||||
// In the first half of the period => price is going up
|
||||
//
|
||||
iDirectionAtPendingTime = 1;
|
||||
} else {
|
||||
// In the second half of the period => price is going down
|
||||
//
|
||||
iDirectionAtPendingTime = -1;
|
||||
}
|
||||
|
||||
fSubmissionTimeFromPending = CalculateTime(fPriceAtPendingTime, fLimitPrice, iDirectionAtPendingTime);
|
||||
}
|
||||
|
||||
return fPendingTime + fSubmissionTimeFromPending;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the expected completion time and the completion price.
|
||||
* Completion time is between 0 and 5 seconds
|
||||
* with 1 sec mean.
|
||||
*
|
||||
* Used to calculate completion time for
|
||||
* both limit (first must get submission time)
|
||||
* and market orders.
|
||||
*
|
||||
* Equivalent of MEE function sequence
|
||||
* 'receive trade' then 'complete the trade request'.
|
||||
*
|
||||
* PARAMETERS:
|
||||
* IN SecurityIndex - unique security index to generate a
|
||||
* unique starting price IN fSubmissionTime - time when the order was
|
||||
* submitted, in seconds from time 0 OUT pCompletionPrice - completion price
|
||||
* of the order
|
||||
*
|
||||
* RETURNS:
|
||||
* the approximated completion time for the trade
|
||||
*
|
||||
*/
|
||||
double CMEESecurity::GetCompletionTime(TIdent SecurityIndex,
|
||||
double fSubmissionTime, // in seconds from time 0
|
||||
CMoney *pCompletionPrice // out
|
||||
) {
|
||||
double fCompletionDelay = NegExp(fMeanCompletionTimeDelay);
|
||||
|
||||
// Clip at 5 seconds to prevent rare, but really long delays
|
||||
//
|
||||
if (fCompletionDelay > 5.0) {
|
||||
fCompletionDelay = 5.0;
|
||||
}
|
||||
|
||||
if (pCompletionPrice != NULL) {
|
||||
*pCompletionPrice = CalculatePrice(SecurityIndex, fSubmissionTime + fCompletionDelay);
|
||||
}
|
||||
|
||||
return fSubmissionTime + fCompletionDelay + fCompletionSUTDelay;
|
||||
}
|
||||
251
external/duckdb/third_party/tpce-tool/main/MEETickerTape.cpp
vendored
Normal file
251
external/duckdb/third_party/tpce-tool/main/MEETickerTape.cpp
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of the MEETickerTape class.
|
||||
* See MEETickerTape.h for a description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/MEETickerTape.h"
|
||||
#include "main/StatusTypeIDs.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
const int CMEETickerTape::LIMIT_TRIGGER_TRADE_QTY = 375;
|
||||
const int CMEETickerTape::RANDOM_TRADE_QTY_1 = 325;
|
||||
const int CMEETickerTape::RANDOM_TRADE_QTY_2 = 425;
|
||||
|
||||
RNGSEED CMEETickerTape::GetRNGSeed(void) {
|
||||
return (m_rnd.GetSeed());
|
||||
}
|
||||
|
||||
void CMEETickerTape::SetRNGSeed(RNGSEED RNGSeed) {
|
||||
m_rnd.SetSeed(RNGSeed);
|
||||
}
|
||||
|
||||
void CMEETickerTape::Initialize(void) {
|
||||
// Set up status and trade types for Market-Feed input
|
||||
//
|
||||
// Submitted
|
||||
strncpy(m_TxnInput.StatusAndTradeType.status_submitted, m_StatusType[eSubmitted].ST_ID_CSTR(),
|
||||
sizeof(m_TxnInput.StatusAndTradeType.status_submitted));
|
||||
// Limit-Buy
|
||||
strncpy(m_TxnInput.StatusAndTradeType.type_limit_buy, m_TradeType[eLimitBuy].TT_ID_CSTR(),
|
||||
sizeof(m_TxnInput.StatusAndTradeType.type_limit_buy));
|
||||
// Limit-Sell
|
||||
strncpy(m_TxnInput.StatusAndTradeType.type_limit_sell, m_TradeType[eLimitSell].TT_ID_CSTR(),
|
||||
sizeof(m_TxnInput.StatusAndTradeType.type_limit_sell));
|
||||
// Stop-Loss
|
||||
strncpy(m_TxnInput.StatusAndTradeType.type_stop_loss, m_TradeType[eStopLoss].TT_ID_CSTR(),
|
||||
sizeof(m_TxnInput.StatusAndTradeType.type_stop_loss));
|
||||
}
|
||||
|
||||
// Constructor - use default RNG seed
|
||||
CMEETickerTape::CMEETickerTape(CMEESUTInterface *pSUT, CMEEPriceBoard *pPriceBoard, CDateTime *pBaseTime,
|
||||
CDateTime *pCurrentTime, const DataFileManager &dfm)
|
||||
: m_pSUT(pSUT), m_pPriceBoard(pPriceBoard), m_BatchIndex(0), m_BatchDuplicates(0), m_rnd(RNGSeedBaseMEETickerTape),
|
||||
m_Enabled(true), m_pBaseTime(pBaseTime), m_pCurrentTime(pCurrentTime), m_StatusType(dfm.StatusTypeDataFile()),
|
||||
m_TradeType(dfm.TradeTypeDataFile()) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
// Constructor - RNG seed provided
|
||||
CMEETickerTape::CMEETickerTape(CMEESUTInterface *pSUT, CMEEPriceBoard *pPriceBoard, CDateTime *pBaseTime,
|
||||
CDateTime *pCurrentTime, RNGSEED RNGSeed, const DataFileManager &dfm)
|
||||
: m_pSUT(pSUT), m_pPriceBoard(pPriceBoard), m_BatchIndex(0), m_BatchDuplicates(0), m_rnd(RNGSeed), m_Enabled(true),
|
||||
m_pBaseTime(pBaseTime), m_pCurrentTime(pCurrentTime), m_StatusType(dfm.StatusTypeDataFile()),
|
||||
m_TradeType(dfm.TradeTypeDataFile()) {
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CMEETickerTape::~CMEETickerTape(void) {
|
||||
}
|
||||
|
||||
bool CMEETickerTape::DisableTicker(void) {
|
||||
m_Enabled = false;
|
||||
return (!m_Enabled);
|
||||
}
|
||||
|
||||
bool CMEETickerTape::EnableTicker(void) {
|
||||
m_Enabled = true;
|
||||
return (m_Enabled);
|
||||
}
|
||||
|
||||
void CMEETickerTape::AddEntry(PTickerEntry pTickerEntry) {
|
||||
if (m_Enabled) {
|
||||
AddToBatch(pTickerEntry);
|
||||
AddArtificialEntries();
|
||||
}
|
||||
}
|
||||
|
||||
void CMEETickerTape::PostLimitOrder(PTradeRequest pTradeRequest) {
|
||||
eTradeTypeID eTradeType;
|
||||
double CurrentPrice = -1.0;
|
||||
PTickerEntry pNewEntry = new TTickerEntry;
|
||||
|
||||
eTradeType = ConvertTradeTypeIdToEnum(pTradeRequest->trade_type_id);
|
||||
|
||||
pNewEntry->price_quote = pTradeRequest->price_quote;
|
||||
strncpy(pNewEntry->symbol, pTradeRequest->symbol, sizeof(pNewEntry->symbol));
|
||||
pNewEntry->trade_qty = LIMIT_TRIGGER_TRADE_QTY;
|
||||
|
||||
CurrentPrice = m_pPriceBoard->GetCurrentPrice(pTradeRequest->symbol).DollarAmount();
|
||||
|
||||
if (((eTradeType == eLimitBuy || eTradeType == eStopLoss) && CurrentPrice <= pTradeRequest->price_quote) ||
|
||||
((eTradeType == eLimitSell) && CurrentPrice >= pTradeRequest->price_quote)) {
|
||||
// Limit Order is in-the-money.
|
||||
pNewEntry->price_quote = CurrentPrice;
|
||||
// Make sure everything is up to date.
|
||||
m_LimitOrderTimers.ProcessExpiredTimers();
|
||||
// Now post the incoming entry.
|
||||
m_InTheMoneyLimitOrderQ.push(pNewEntry);
|
||||
} else {
|
||||
// Limit Order is not in-the-money.
|
||||
pNewEntry->price_quote = pTradeRequest->price_quote;
|
||||
double TriggerTimeDelay;
|
||||
double fCurrentTime = *m_pCurrentTime - *m_pBaseTime;
|
||||
|
||||
// GetSubmissionTime returns a value relative to time 0, so we
|
||||
// need to substract off the value for the current time to get
|
||||
// the delay time relative to now.
|
||||
TriggerTimeDelay =
|
||||
m_pPriceBoard->GetSubmissionTime(pNewEntry->symbol, fCurrentTime, pNewEntry->price_quote, eTradeType) -
|
||||
fCurrentTime;
|
||||
m_LimitOrderTimers.StartTimer(TriggerTimeDelay, this, &CMEETickerTape::AddLimitTrigger, pNewEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void CMEETickerTape::AddLimitTrigger(PTickerEntry pTickerEntry) {
|
||||
m_InTheMoneyLimitOrderQ.push(pTickerEntry);
|
||||
}
|
||||
|
||||
void CMEETickerTape::AddArtificialEntries(void) {
|
||||
TIdent SecurityIndex;
|
||||
TTickerEntry TickerEntry;
|
||||
int TotalEntryCount = 0;
|
||||
static const int PaddingLimit =
|
||||
(max_feed_len / 10) - 1; // NOTE: 10 here represents the ratio of TR to MF transactions
|
||||
static const int PaddingLimitForAll = PaddingLimit; // MAX (trigger+artificial) entries
|
||||
static const int PaddingLimitForTriggers = PaddingLimit; // MAX (triggered) entries
|
||||
|
||||
while (TotalEntryCount < PaddingLimitForTriggers && !m_InTheMoneyLimitOrderQ.empty()) {
|
||||
PTickerEntry pEntry = m_InTheMoneyLimitOrderQ.front();
|
||||
AddToBatch(pEntry);
|
||||
delete pEntry;
|
||||
m_InTheMoneyLimitOrderQ.pop();
|
||||
TotalEntryCount++;
|
||||
}
|
||||
|
||||
while (TotalEntryCount < PaddingLimitForAll) {
|
||||
TickerEntry.trade_qty = (m_rnd.RndPercent(50)) ? RANDOM_TRADE_QTY_1 : RANDOM_TRADE_QTY_2;
|
||||
|
||||
SecurityIndex = m_rnd.RndInt64Range(0, m_pPriceBoard->m_iNumberOfSecurities - 1);
|
||||
TickerEntry.price_quote = (m_pPriceBoard->GetCurrentPrice(SecurityIndex)).DollarAmount();
|
||||
m_pPriceBoard->GetSymbol(SecurityIndex, TickerEntry.symbol, static_cast<INT32>(sizeof(TickerEntry.symbol)));
|
||||
|
||||
AddToBatch(&TickerEntry);
|
||||
TotalEntryCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void CMEETickerTape::AddToBatch(PTickerEntry pTickerEntry) {
|
||||
// Check to see if this symbol already exists in the batch
|
||||
for (int i = 0; i < m_BatchIndex; i++) {
|
||||
if (strncmp(pTickerEntry->symbol, m_TxnInput.Entries[i].symbol, cSYMBOL_len) == 0) {
|
||||
m_BatchDuplicates++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the ticker to the batch
|
||||
m_TxnInput.Entries[m_BatchIndex++] = *pTickerEntry;
|
||||
|
||||
// Buffer is full, time for Market-Feed.
|
||||
if (max_feed_len == m_BatchIndex) {
|
||||
m_TxnInput.unique_symbols = (max_feed_len - m_BatchDuplicates);
|
||||
m_pSUT->MarketFeed(&m_TxnInput);
|
||||
m_BatchIndex = 0;
|
||||
m_BatchDuplicates = 0;
|
||||
}
|
||||
}
|
||||
|
||||
eTradeTypeID CMEETickerTape::ConvertTradeTypeIdToEnum(char *pTradeType) {
|
||||
// Convert character trade type to enumeration
|
||||
switch (pTradeType[0]) {
|
||||
case 'T':
|
||||
switch (pTradeType[1]) {
|
||||
case 'L':
|
||||
switch (pTradeType[2]) {
|
||||
case 'B':
|
||||
return (eLimitBuy);
|
||||
case 'S':
|
||||
return (eLimitSell);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
switch (pTradeType[2]) {
|
||||
case 'B':
|
||||
return (eMarketBuy);
|
||||
case 'S':
|
||||
return (eMarketSell);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
switch (pTradeType[2]) {
|
||||
case 'L':
|
||||
return (eStopLoss);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Throw exception - should never get here
|
||||
assert(false); // this should never happen
|
||||
|
||||
return eMarketBuy; // silence compiler warning about not all control paths
|
||||
// returning a value
|
||||
}
|
||||
155
external/duckdb/third_party/tpce-tool/main/MEETradingFloor.cpp
vendored
Normal file
155
external/duckdb/third_party/tpce-tool/main/MEETradingFloor.cpp
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implemenation of the MEETradingFloor class.
|
||||
* See MEETradingFloor.h for a description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/MEETradingFloor.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
RNGSEED CMEETradingFloor::GetRNGSeed(void) {
|
||||
return (m_rnd.GetSeed());
|
||||
}
|
||||
|
||||
void CMEETradingFloor::SetRNGSeed(RNGSEED RNGSeed) {
|
||||
m_rnd.SetSeed(RNGSeed);
|
||||
}
|
||||
|
||||
// Constructor - use default RNG seed
|
||||
CMEETradingFloor::CMEETradingFloor(CMEESUTInterface *pSUT, CMEEPriceBoard *pPriceBoard, CMEETickerTape *pTickerTape,
|
||||
CDateTime *pBaseTime, CDateTime *pCurrentTime)
|
||||
: m_pSUT(pSUT), m_pPriceBoard(pPriceBoard), m_pTickerTape(pTickerTape), m_pBaseTime(pBaseTime),
|
||||
m_pCurrentTime(pCurrentTime), m_rnd(RNGSeedBaseMEETradingFloor), m_OrderProcessingDelayMean(1.0) {
|
||||
}
|
||||
|
||||
// Constructor - RNG seed provided
|
||||
CMEETradingFloor::CMEETradingFloor(CMEESUTInterface *pSUT, CMEEPriceBoard *pPriceBoard, CMEETickerTape *pTickerTape,
|
||||
CDateTime *pBaseTime, CDateTime *pCurrentTime, RNGSEED RNGSeed)
|
||||
: m_pSUT(pSUT), m_pPriceBoard(pPriceBoard), m_pTickerTape(pTickerTape), m_pBaseTime(pBaseTime),
|
||||
m_pCurrentTime(pCurrentTime), m_rnd(RNGSeed), m_OrderProcessingDelayMean(1.0) {
|
||||
}
|
||||
|
||||
CMEETradingFloor::~CMEETradingFloor(void) {
|
||||
}
|
||||
|
||||
inline double CMEETradingFloor::GenProcessingDelay(double Mean) {
|
||||
double Result = RoundToNearestNsec(m_rnd.RndDoubleNegExp(Mean));
|
||||
|
||||
if (Result > m_MaxOrderProcessingDelay) {
|
||||
return (m_MaxOrderProcessingDelay);
|
||||
} else {
|
||||
return (Result);
|
||||
}
|
||||
}
|
||||
|
||||
INT32 CMEETradingFloor::SubmitTradeRequest(PTradeRequest pTradeRequest) {
|
||||
switch (pTradeRequest->eAction) {
|
||||
case eMEEProcessOrder: { // Use {...} to keep compiler from complaining that
|
||||
// other cases/default skip initialization of
|
||||
// pNewOrder.
|
||||
// This is either a market order or a limit order that has been
|
||||
// triggered, so it gets traded right away. Make a copy in storage under
|
||||
// our control.
|
||||
PTradeRequest pNewOrder = new TTradeRequest;
|
||||
*pNewOrder = *pTradeRequest;
|
||||
return (m_OrderTimers.StartTimer(GenProcessingDelay(m_OrderProcessingDelayMean), this,
|
||||
&CMEETradingFloor::SendTradeResult, pNewOrder));
|
||||
} // Use {...} to keep compiler from complaining that other cases/default
|
||||
// skip initialization of pNewOrder.
|
||||
case eMEESetLimitOrderTrigger:
|
||||
// This is a limit order
|
||||
m_pTickerTape->PostLimitOrder(pTradeRequest);
|
||||
return (m_OrderTimers.ProcessExpiredTimers());
|
||||
default:
|
||||
// Throw and exception - SHOULD NEVER GET HERE!
|
||||
return (m_OrderTimers.ProcessExpiredTimers());
|
||||
}
|
||||
}
|
||||
|
||||
INT32 CMEETradingFloor::GenerateTradeResult(void) {
|
||||
return (m_OrderTimers.ProcessExpiredTimers());
|
||||
}
|
||||
|
||||
void CMEETradingFloor::SendTradeResult(PTradeRequest pTradeRequest) {
|
||||
eTradeTypeID eTradeType;
|
||||
TTradeResultTxnInput TxnInput;
|
||||
TTickerEntry TickerEntry;
|
||||
double CurrentPrice = -1.0;
|
||||
|
||||
eTradeType = m_pTickerTape->ConvertTradeTypeIdToEnum(pTradeRequest->trade_type_id);
|
||||
CurrentPrice = m_pPriceBoard->GetCurrentPrice(pTradeRequest->symbol).DollarAmount();
|
||||
|
||||
// Populate Trade-Result inputs, and send to SUT
|
||||
TxnInput.trade_id = pTradeRequest->trade_id;
|
||||
|
||||
// Make sure the Trade-Result has the right price based on the type of
|
||||
// trade.
|
||||
if ((eTradeType == eLimitBuy && pTradeRequest->price_quote < CurrentPrice) ||
|
||||
(eTradeType == eLimitSell && pTradeRequest->price_quote > CurrentPrice)) {
|
||||
TxnInput.trade_price = pTradeRequest->price_quote;
|
||||
} else {
|
||||
TxnInput.trade_price = CurrentPrice;
|
||||
}
|
||||
|
||||
m_pSUT->TradeResult(&TxnInput);
|
||||
|
||||
// Populate Ticker Entry information
|
||||
strncpy(TickerEntry.symbol, pTradeRequest->symbol, sizeof(TickerEntry.symbol));
|
||||
TickerEntry.trade_qty = pTradeRequest->trade_qty;
|
||||
|
||||
// Note that the Trade-Result sent out above does not always use
|
||||
// the current price. We're about to "lie" by setting the ticker entry
|
||||
// price to the current price regardless of how the Trade-Result
|
||||
// price was actually set. We do this to preserve the continuity
|
||||
// of the price curve. This is important because the ticker prices
|
||||
// are used by transactions to make decisions. It is possible for
|
||||
// the Trade-Result price to be out of sync with the price curve,
|
||||
// and putting this price into the ticker stream will alter the
|
||||
// behavior of other transactions. If you're having a guilt-attack
|
||||
// about this lie (or are just plain curious), comment out the
|
||||
// assignment using CurrentPrice and uncomment the assignment
|
||||
// using TxnInput.trade_price.
|
||||
//
|
||||
TickerEntry.price_quote = CurrentPrice;
|
||||
// TickerEntry.price_quote = TxnInput.trade_price;
|
||||
|
||||
m_pTickerTape->AddEntry(&TickerEntry);
|
||||
|
||||
delete pTradeRequest;
|
||||
}
|
||||
200
external/duckdb/third_party/tpce-tool/main/Person.cpp
vendored
Normal file
200
external/duckdb/third_party/tpce-tool/main/Person.cpp
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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
|
||||
* - Sergey Vasilevskiy
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/EGenTables_stdafx.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
// Percentages used in determining gender.
|
||||
const int iPercentGenderIsMale = 49;
|
||||
|
||||
/*
|
||||
* Initializes in-memory representation of names files.
|
||||
*/
|
||||
CPerson::CPerson(const DataFileManager &dfm, TIdent iStartFromCustomer, bool bCacheEnabled)
|
||||
: m_LastNames(dfm.LastNameDataFile()), m_MaleFirstNames(dfm.MaleFirstNameDataFile()),
|
||||
m_FemaleFirstNames(dfm.FemaleFirstNameDataFile()), m_bCacheEnabled(bCacheEnabled), m_iCacheSize(0),
|
||||
m_iCacheOffset(0), INVALID_NAME_CACHE_ENTRY(-1), INVALID_GENDER_CACHE_ENTRY('X') {
|
||||
if (m_bCacheEnabled) {
|
||||
m_iCacheSize = iDefaultLoadUnitSize;
|
||||
m_iCacheOffset = iTIdentShift + iStartFromCustomer;
|
||||
m_FirstNameCache = new int[m_iCacheSize];
|
||||
m_LastNameCache = new int[m_iCacheSize];
|
||||
m_GenderCache = new char[m_iCacheSize];
|
||||
for (int i = 0; i < m_iCacheSize; i++) {
|
||||
m_FirstNameCache[i] = INVALID_NAME_CACHE_ENTRY;
|
||||
m_LastNameCache[i] = INVALID_NAME_CACHE_ENTRY;
|
||||
m_GenderCache[i] = INVALID_GENDER_CACHE_ENTRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate in-memory representation of names files.
|
||||
*/
|
||||
CPerson::~CPerson() {
|
||||
if (m_bCacheEnabled) {
|
||||
delete[] m_FirstNameCache;
|
||||
delete[] m_LastNameCache;
|
||||
delete[] m_GenderCache;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Resets the cache.
|
||||
*/
|
||||
void CPerson::InitNextLoadUnit(TIdent iCacheOffsetIncrement) {
|
||||
if (m_bCacheEnabled) {
|
||||
m_iCacheOffset += iCacheOffsetIncrement;
|
||||
for (int i = 0; i < m_iCacheSize; i++) {
|
||||
m_FirstNameCache[i] = INVALID_NAME_CACHE_ENTRY;
|
||||
m_LastNameCache[i] = INVALID_NAME_CACHE_ENTRY;
|
||||
m_GenderCache[i] = INVALID_GENDER_CACHE_ENTRY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the last name for a particular customer id.
|
||||
* It'll always be the same for the same customer id.
|
||||
*/
|
||||
const string &CPerson::GetLastName(TIdent CID) {
|
||||
return getName<LastNameDataFile_t>(CID, m_LastNames, m_LastNameCache, RNGSeedBaseLastName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the first name for a particular customer id.
|
||||
* Determines gender first.
|
||||
*/
|
||||
const string &CPerson::GetFirstName(TIdent CID) {
|
||||
if (IsMaleGender(CID)) {
|
||||
return getName<MaleFirstNameDataFile_t>(CID, m_MaleFirstNames, m_FirstNameCache, RNGSeedBaseFirstName);
|
||||
} else {
|
||||
return getName<FemaleFirstNameDataFile_t>(CID, m_FemaleFirstNames, m_FirstNameCache, RNGSeedBaseFirstName);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Returns the middle name.
|
||||
*/
|
||||
char CPerson::GetMiddleName(TIdent CID) {
|
||||
RNGSEED OldSeed;
|
||||
char cMiddleInitial[2];
|
||||
|
||||
OldSeed = m_rnd.GetSeed();
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseMiddleInitial, (RNGSEED)CID));
|
||||
cMiddleInitial[1] = '\0';
|
||||
m_rnd.RndAlphaNumFormatted(cMiddleInitial, "a");
|
||||
m_rnd.SetSeed(OldSeed);
|
||||
return (cMiddleInitial[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the gender character for a particular customer id.
|
||||
*/
|
||||
char CPerson::GetGender(TIdent CID) {
|
||||
RNGSEED OldSeed;
|
||||
char cGender;
|
||||
|
||||
// It is possible (and expected) to get CID values that are oustide the
|
||||
// current load unit. For example, AccountPermission CIDs and Broker IDs
|
||||
// can be outside the current load unit. These "out of bounds" CIDs are not
|
||||
// cached so we need to account for this.
|
||||
TIdent index = CID - m_iCacheOffset;
|
||||
bool bCheckCache = (index >= 0 && index < m_iCacheSize);
|
||||
|
||||
// Use the cache if we can.
|
||||
if (m_bCacheEnabled && bCheckCache && (INVALID_GENDER_CACHE_ENTRY != m_GenderCache[index])) {
|
||||
return m_GenderCache[index];
|
||||
}
|
||||
|
||||
// We couldn't use the cache.
|
||||
|
||||
OldSeed = m_rnd.GetSeed();
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseGender, (RNGSEED)CID));
|
||||
|
||||
// Find out gender
|
||||
if (m_rnd.RndPercent(iPercentGenderIsMale)) {
|
||||
cGender = 'M';
|
||||
} else {
|
||||
cGender = 'F';
|
||||
}
|
||||
|
||||
// Cache the result if appropriate.
|
||||
if (m_bCacheEnabled && bCheckCache) {
|
||||
m_GenderCache[index] = cGender;
|
||||
}
|
||||
|
||||
// Restore the RNG
|
||||
m_rnd.SetSeed(OldSeed);
|
||||
return (cGender);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE is a customer id is male
|
||||
*/
|
||||
bool CPerson::IsMaleGender(TIdent CID) {
|
||||
return GetGender(CID) == 'M';
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate tax id
|
||||
*/
|
||||
void CPerson::GetTaxID(TIdent CID, char *buf) {
|
||||
RNGSEED OldSeed;
|
||||
|
||||
OldSeed = m_rnd.GetSeed();
|
||||
|
||||
// NOTE: the call to RndAlphaNumFormatted "consumes" an RNG value
|
||||
// for EACH character in the format string. Therefore, to avoid getting
|
||||
// tax ID's that overlap N-1 out of N characters, multiply the offset into
|
||||
// the sequence by N to get a unique range of values.
|
||||
m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseTaxID, ((RNGSEED)CID * TaxIDFmt_len)));
|
||||
m_rnd.RndAlphaNumFormatted(buf, TaxIDFmt);
|
||||
m_rnd.SetSeed(OldSeed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get first name, last name, and tax id.
|
||||
*/
|
||||
void CPerson::GetFirstLastAndTaxID(TIdent C_ID, char *szFirstName, char *szLastName, char *szTaxID) {
|
||||
// Fill in the last name
|
||||
strncpy(szLastName, GetLastName(C_ID).c_str(), cL_NAME_len);
|
||||
// Fill in the first name
|
||||
strncpy(szFirstName, GetFirstName(C_ID).c_str(), cF_NAME_len);
|
||||
// Fill in the tax id
|
||||
GetTaxID(C_ID, szTaxID);
|
||||
}
|
||||
54
external/duckdb/third_party/tpce-tool/main/SectorTable.cpp
vendored
Normal file
54
external/duckdb/third_party/tpce-tool/main/SectorTable.cpp
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/SectorTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CSectorTable::CSectorTable(const SectorDataFile_t &dataFile) : FixedTable<SectorDataFile_t, SECTOR_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
CSectorTable::~CSectorTable() {
|
||||
}
|
||||
|
||||
void CSectorTable::LoadTableRow() {
|
||||
const SectorDataFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
strncpy(tableRow.SC_ID, dataRecord.SC_ID_CSTR(), sizeof(tableRow.SC_ID));
|
||||
strncpy(tableRow.SC_NAME, dataRecord.SC_NAME_CSTR(), sizeof(tableRow.SC_NAME));
|
||||
}
|
||||
55
external/duckdb/third_party/tpce-tool/main/StatusTypeTable.cpp
vendored
Normal file
55
external/duckdb/third_party/tpce-tool/main/StatusTypeTable.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/StatusTypeTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CStatusTypeTable::CStatusTypeTable(const StatusTypeDataFile_t &dataFile)
|
||||
: FixedTable<StatusTypeDataFile_t, STATUS_TYPE_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
CStatusTypeTable::~CStatusTypeTable() {
|
||||
}
|
||||
|
||||
void CStatusTypeTable::LoadTableRow() {
|
||||
const StatusTypeDataFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
strncpy(tableRow.ST_ID, dataRecord.ST_ID_CSTR(), sizeof(tableRow.ST_ID));
|
||||
strncpy(tableRow.ST_NAME, dataRecord.ST_NAME_CSTR(), sizeof(tableRow.ST_NAME));
|
||||
}
|
||||
55
external/duckdb/third_party/tpce-tool/main/TaxRateTable.cpp
vendored
Normal file
55
external/duckdb/third_party/tpce-tool/main/TaxRateTable.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/TaxRateTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
TaxRateTable::TaxRateTable(const CTaxRateFile &dataFile) : FixedTable<CTaxRateFile, TAX_RATE_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
TaxRateTable::~TaxRateTable() {
|
||||
}
|
||||
|
||||
void TaxRateTable::LoadTableRow() {
|
||||
const ITaxRateFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
strncpy(tableRow.TX_ID, dataRecord.TX_ID_CSTR(), sizeof(tableRow.TX_ID));
|
||||
strncpy(tableRow.TX_NAME, dataRecord.TX_NAME_CSTR(), sizeof(tableRow.TX_NAME));
|
||||
tableRow.TX_RATE = dataRecord.TX_RATE();
|
||||
}
|
||||
1255
external/duckdb/third_party/tpce-tool/main/TradeGen.cpp
vendored
Normal file
1255
external/duckdb/third_party/tpce-tool/main/TradeGen.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
57
external/duckdb/third_party/tpce-tool/main/TradeTypeTable.cpp
vendored
Normal file
57
external/duckdb/third_party/tpce-tool/main/TradeTypeTable.cpp
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include "main/TradeTypeTable.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CTradeTypeTable::CTradeTypeTable(const TradeTypeDataFile_t &dataFile)
|
||||
: FixedTable<TradeTypeDataFile_t, TRADE_TYPE_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
CTradeTypeTable::~CTradeTypeTable() {
|
||||
}
|
||||
|
||||
void CTradeTypeTable::LoadTableRow() {
|
||||
const TradeTypeDataFileRecord &dataRecord(df[recordIdx]);
|
||||
|
||||
strncpy(tableRow.TT_ID, dataRecord.TT_ID_CSTR(), sizeof(tableRow.TT_ID));
|
||||
tableRow.TT_IS_MRKT = dataRecord.TT_IS_MRKT();
|
||||
tableRow.TT_IS_SELL = dataRecord.TT_IS_SELL();
|
||||
strncpy(tableRow.TT_NAME, dataRecord.TT_NAME_CSTR(), sizeof(tableRow.TT_NAME));
|
||||
}
|
||||
129
external/duckdb/third_party/tpce-tool/main/WheelTime.cpp
vendored
Normal file
129
external/duckdb/third_party/tpce-tool/main/WheelTime.cpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Description: Implementation of the CWheelTime class.
|
||||
* See WheelTime.h for a high level description.
|
||||
******************************************************************************/
|
||||
|
||||
#include "main/WheelTime.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CWheelTime::CWheelTime(PWheelConfig pWheelConfig) : m_pWheelConfig(pWheelConfig), m_Cycles(0), m_Index(0) {
|
||||
}
|
||||
|
||||
CWheelTime::CWheelTime(PWheelConfig pWheelConfig, INT32 cycles, INT32 index)
|
||||
: m_pWheelConfig(pWheelConfig), m_Cycles(cycles), m_Index(index) {
|
||||
}
|
||||
|
||||
CWheelTime::CWheelTime(PWheelConfig pWheelConfig, CDateTime &Base, CDateTime &Now, INT32 offset)
|
||||
: m_pWheelConfig(pWheelConfig) {
|
||||
Set(Base, Now);
|
||||
Add(offset);
|
||||
}
|
||||
|
||||
CWheelTime::~CWheelTime(void) {
|
||||
}
|
||||
|
||||
void CWheelTime::Add(INT32 Interval) {
|
||||
// DJ - should throw error if Interval >= m_pWheelConfig->WheelSize?
|
||||
m_Cycles += Interval / m_pWheelConfig->WheelSize;
|
||||
m_Index += Interval % m_pWheelConfig->WheelSize;
|
||||
if (m_Index >= m_pWheelConfig->WheelSize) {
|
||||
// Handle wrapping in the wheel - assume we don't allow multi-cycle
|
||||
// intervals
|
||||
m_Cycles++;
|
||||
m_Index -= m_pWheelConfig->WheelSize;
|
||||
}
|
||||
}
|
||||
|
||||
INT32 CWheelTime::Offset(const CWheelTime &Time) {
|
||||
INT32 Interval;
|
||||
|
||||
Interval = (m_Cycles - Time.m_Cycles) * m_pWheelConfig->WheelSize;
|
||||
Interval += (m_Index - Time.m_Index);
|
||||
return (Interval);
|
||||
}
|
||||
|
||||
void CWheelTime::Set(INT32 cycles, INT32 index) {
|
||||
m_Cycles = cycles;
|
||||
m_Index = index; // DJ - should throw error if Index >= m_pWheelConfig->WheelSize
|
||||
}
|
||||
|
||||
// Set is overloaded. This version is used by the timer wheel.
|
||||
void CWheelTime::Set(CDateTime &Base, CDateTime &Now) {
|
||||
INT32 offset; // offset from BaseTime in milliseconds
|
||||
|
||||
// DJ - If Now < Base, then we should probably throw an exception
|
||||
|
||||
offset = Now.DiffInMilliSeconds(Base) / m_pWheelConfig->WheelResolution; // convert based on wheel resolution
|
||||
m_Cycles = offset / m_pWheelConfig->WheelSize;
|
||||
m_Index = offset % m_pWheelConfig->WheelSize;
|
||||
}
|
||||
|
||||
// Set is overloaded. This version is used by the event wheel.
|
||||
void CWheelTime::Set(CDateTime *pBase, CDateTime *pNow) {
|
||||
INT32 offset; // offset from BaseTime in milliseconds
|
||||
|
||||
// DJ - If Now < Base, then we should probably throw an exception
|
||||
|
||||
offset = pNow->DiffInMilliSeconds(pBase) / m_pWheelConfig->WheelResolution; // convert based on wheel resolution
|
||||
m_Cycles = offset / m_pWheelConfig->WheelSize;
|
||||
m_Index = offset % m_pWheelConfig->WheelSize;
|
||||
}
|
||||
|
||||
bool CWheelTime::operator<(const CWheelTime &Time) {
|
||||
return (m_Cycles == Time.m_Cycles) ? (m_Index < Time.m_Index) : (m_Cycles < Time.m_Cycles);
|
||||
}
|
||||
|
||||
CWheelTime &CWheelTime::operator=(const CWheelTime &Time) {
|
||||
m_pWheelConfig = Time.m_pWheelConfig;
|
||||
m_Cycles = Time.m_Cycles;
|
||||
m_Index = Time.m_Index;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CWheelTime &CWheelTime::operator+=(const INT32 &Interval) {
|
||||
Add(Interval);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CWheelTime CWheelTime::operator++(INT32) {
|
||||
Add(1);
|
||||
return *this;
|
||||
}
|
||||
60
external/duckdb/third_party/tpce-tool/main/ZipCodeTable.cpp
vendored
Normal file
60
external/duckdb/third_party/tpce-tool/main/ZipCodeTable.cpp
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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
|
||||
* - Doug Johnson
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "main/ZipCodeTable.h"
|
||||
|
||||
using namespace TPCE;
|
||||
|
||||
CZipCodeTable::CZipCodeTable(const ZipCodeDataFile_t &dataFile)
|
||||
: FixedTable<ZipCodeDataFile_t, ZIP_CODE_ROW>(dataFile) {
|
||||
}
|
||||
|
||||
CZipCodeTable::~CZipCodeTable() {
|
||||
}
|
||||
|
||||
unsigned int CZipCodeTable::MaxRecordIdx() const {
|
||||
return df.size(df.UniqueRecordsOnly); // unique records only
|
||||
}
|
||||
|
||||
void CZipCodeTable::LoadTableRow() {
|
||||
const ZipCodeDataFileRecord &dataRecord(df.getUniqueRecord(recordIdx));
|
||||
|
||||
strncpy(tableRow.ZC_CODE, dataRecord.ZC_CODE_CSTR(), sizeof(tableRow.ZC_CODE));
|
||||
strncpy(tableRow.ZC_DIV, dataRecord.ZC_DIV_CSTR(), sizeof(tableRow.ZC_DIV));
|
||||
strncpy(tableRow.ZC_TOWN, dataRecord.ZC_TOWN_CSTR(), sizeof(tableRow.ZC_TOWN));
|
||||
}
|
||||
156
external/duckdb/third_party/tpce-tool/main/bucketsimulator.cpp
vendored
Normal file
156
external/duckdb/third_party/tpce-tool/main/bucketsimulator.cpp
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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
|
||||
* - Cecil Reames
|
||||
*/
|
||||
|
||||
#include "utilities/threading.h"
|
||||
#include "main/unusedflag.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iomanip>
|
||||
|
||||
#include "main/bucketsimulator.h"
|
||||
|
||||
namespace TPCE {
|
||||
|
||||
BucketSimulator::BucketSimulator(int iterstart, int itercount, TIdent iCustomerCount, INT64 simorders,
|
||||
TPCE::RNGSEED base_seed, BucketProgress &progress)
|
||||
: m_rnd(), m_buckets(NULL), m_custcount(iCustomerCount), m_iterstart(iterstart), m_itercount(itercount),
|
||||
m_baseseed(base_seed), m_simorders(simorders),
|
||||
m_maxbucket(static_cast<int>(iCustomerCount / iDefaultLoadUnitSize)), m_progress(progress) {
|
||||
if (iCustomerCount % iDefaultLoadUnitSize != 0) {
|
||||
throw std::range_error("The customer count must be an integral "
|
||||
"multiple of the load unit size!");
|
||||
}
|
||||
if (m_maxbucket < 2) {
|
||||
throw std::range_error("Bucket simulator must have at least 2 buckets!");
|
||||
}
|
||||
m_buckets = new INT64[m_maxbucket];
|
||||
}
|
||||
|
||||
BucketSimulator::~BucketSimulator() {
|
||||
delete[] m_buckets;
|
||||
}
|
||||
|
||||
// Calculate the standard deviation of the current bucket
|
||||
// Use straightforward method rather than sum of squares...
|
||||
double BucketSimulator::calc_stddev() {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < m_maxbucket; ++i) {
|
||||
sum += m_buckets[i];
|
||||
}
|
||||
double mean = sum / (double)m_maxbucket;
|
||||
|
||||
double sumdev2 = 0;
|
||||
for (int i = 0; i < m_maxbucket; ++i) {
|
||||
sumdev2 += (m_buckets[i] - mean) * (m_buckets[i] - mean);
|
||||
}
|
||||
double stddev = sqrt(sumdev2 / (double)(m_maxbucket - 1));
|
||||
|
||||
return stddev;
|
||||
}
|
||||
|
||||
// Simulates one run and returns the standard deviation of the buckets
|
||||
// iterations - Number of "orders" to simulate (note that we don't take into
|
||||
// account the 1% rollbacks)
|
||||
double BucketSimulator::simulate_onerun(INT64 iorders) {
|
||||
int bucket;
|
||||
|
||||
memset(m_buckets, 0, sizeof(m_buckets[0]) * m_maxbucket);
|
||||
|
||||
for (INT64 i = 0; i < iorders; ++i) {
|
||||
bucket = m_rnd.RndIntRange(0, static_cast<int>((m_custcount - 1) / static_cast<TIdent>(iDefaultLoadUnitSize)));
|
||||
m_buckets[bucket] += 1;
|
||||
}
|
||||
|
||||
return calc_stddev();
|
||||
}
|
||||
|
||||
// Perform all of the simulations this instance was constructed with and return
|
||||
// the maximum standard deviation
|
||||
double BucketSimulator::simulate() {
|
||||
double max_stddev = 0;
|
||||
TPCE::RNGSEED seed = m_rnd.RndNthElement(m_baseseed, (RNGSEED)(m_iterstart * m_simorders * RND_STEP_PER_ORDER));
|
||||
m_rnd.SetSeed(seed);
|
||||
for (int i = 0; i < m_itercount; ++i) {
|
||||
TPCE::RNGSEED current_seed = m_rnd.GetSeed();
|
||||
double stddev = simulate_onerun(m_simorders);
|
||||
|
||||
std::ostringstream strm;
|
||||
strm << "StdDev for run " << i + m_iterstart << " is " << std::setprecision(3) << std::fixed << stddev
|
||||
<< ", seed was " << current_seed;
|
||||
m_progress.message(strm.str(), 1);
|
||||
|
||||
if (max_stddev < stddev) {
|
||||
max_stddev = stddev;
|
||||
}
|
||||
if (!m_progress.report(stddev)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return max_stddev;
|
||||
}
|
||||
|
||||
// Entry point to be run as a thread
|
||||
void BucketSimulator::run(void *thread UNUSED) {
|
||||
simulate();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BucketProgress::BucketProgress(double acceptable_stddev, int total_in, int verbosity, std::ostream *output)
|
||||
: ProgressMeter(total_in, verbosity, output), acceptable_stddev_(acceptable_stddev), max_stddev_(0) {
|
||||
}
|
||||
|
||||
void BucketProgress::display_message(std::ostream &out) const {
|
||||
ProgressMeter::display_message(out);
|
||||
out << " stddev=" << max_stddev_;
|
||||
}
|
||||
|
||||
bool BucketProgress::report(double stddev) {
|
||||
inc();
|
||||
TPCE::Locker<ProgressMeter> locker(*this);
|
||||
if (max_stddev_ < stddev) {
|
||||
max_stddev_ = stddev;
|
||||
}
|
||||
return (max_stddev_ < acceptable_stddev_);
|
||||
}
|
||||
|
||||
double BucketProgress::max_stddev() {
|
||||
TPCE::Locker<ProgressMeter> locker(*this);
|
||||
return max_stddev_;
|
||||
}
|
||||
|
||||
} // namespace TPCE
|
||||
136
external/duckdb/third_party/tpce-tool/main/progressmeter.cpp
vendored
Normal file
136
external/duckdb/third_party/tpce-tool/main/progressmeter.cpp
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "utilities/threading.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "main/progressmeter.h"
|
||||
#include "main/strutil.h"
|
||||
|
||||
namespace TPCE {
|
||||
|
||||
// total - The total number of tasks to complete before the job is done.
|
||||
ProgressMeter::ProgressMeter(int total_in, int verbosity, std::ostream *output)
|
||||
: m_total(total_in), m_current(0), m_display_interval(10), m_start_time(), m_last_time(m_start_time),
|
||||
m_output(output), m_verbosity(verbosity), m_mutex() {
|
||||
}
|
||||
|
||||
// val - minimum number of seconds between automatic display updates
|
||||
// set to -1 to disable automatic displays
|
||||
void ProgressMeter::set_display_interval(int val) {
|
||||
TPCE::Locker<ProgressMeter> locker(*this);
|
||||
m_display_interval = val;
|
||||
}
|
||||
|
||||
int ProgressMeter::display_interval() const {
|
||||
TPCE::Locker<const ProgressMeter> locker(*this);
|
||||
return m_display_interval;
|
||||
}
|
||||
|
||||
// Displays the current progress and an estimated time to finish
|
||||
void ProgressMeter::display() const {
|
||||
TPCE::Locker<const ProgressMeter> locker(*this);
|
||||
display_message(*m_output);
|
||||
(*m_output) << std::endl;
|
||||
}
|
||||
|
||||
// Displays a progress message to the specified output stream
|
||||
// Lock progress meter before calling this function!
|
||||
//
|
||||
// output - output stream to display progress to
|
||||
void ProgressMeter::display_message(std::ostream &out) const {
|
||||
CDateTime now;
|
||||
INT32 elapsed_in_ms = now.DiffInMilliSeconds(m_start_time);
|
||||
double rate = static_cast<double>(elapsed_in_ms) / static_cast<double>(m_current) / 1000.0;
|
||||
out << m_current << "/" << m_total << " (" << m_current * 100 / m_total << "%)"
|
||||
<< " [Remain: " << int64totimestr((int)(rate * (double)(m_total - m_current))) << ", "
|
||||
<< "Elapsed: " << int64totimestr(elapsed_in_ms / 1000) << "]";
|
||||
}
|
||||
|
||||
// Notifies the progress meter that some tasks have been completed. If there
|
||||
// hasn't been a display update within display_interval seconds then an update
|
||||
// will be emitted to the output stream.
|
||||
//
|
||||
// count - number of tasks completed
|
||||
// output - output stream to display progress to
|
||||
void ProgressMeter::inc(int count) {
|
||||
CDateTime now;
|
||||
{
|
||||
TPCE::Locker<ProgressMeter> locker(*this);
|
||||
m_current += count;
|
||||
if (m_verbosity <= 0 || m_display_interval < 0 ||
|
||||
now.DiffInMilliSeconds(m_last_time) <= m_display_interval * 1000) {
|
||||
return;
|
||||
}
|
||||
m_last_time.Set();
|
||||
}
|
||||
display();
|
||||
}
|
||||
|
||||
// Return current count
|
||||
int ProgressMeter::current() const {
|
||||
TPCE::Locker<const ProgressMeter> locker(*this);
|
||||
return m_current;
|
||||
}
|
||||
|
||||
// Return total count
|
||||
int ProgressMeter::total() const {
|
||||
TPCE::Locker<const ProgressMeter> locker(*this);
|
||||
return m_total;
|
||||
}
|
||||
|
||||
// Display a message if the verbosity level is greater than message level
|
||||
//
|
||||
// mesg - message to display
|
||||
// level - verbosity level to display at
|
||||
void ProgressMeter::message(const std::string &mesg, int level) {
|
||||
TPCE::Locker<ProgressMeter> locker(*this);
|
||||
if (level >= m_verbosity) {
|
||||
return;
|
||||
}
|
||||
(*m_output) << mesg << std::endl;
|
||||
}
|
||||
|
||||
void ProgressMeter::lock() const {
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void ProgressMeter::unlock() const {
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
} // namespace TPCE
|
||||
55
external/duckdb/third_party/tpce-tool/main/progressmeterinterface.cpp
vendored
Normal file
55
external/duckdb/third_party/tpce-tool/main/progressmeterinterface.cpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "main/progressmeterinterface.h"
|
||||
#include "main/unusedflag.h"
|
||||
|
||||
namespace TPCE {
|
||||
|
||||
// Dummy implementation in case someone wants to have a null progress meter
|
||||
ProgressMeterInterface::~ProgressMeterInterface() {
|
||||
}
|
||||
|
||||
void ProgressMeterInterface::display() const {
|
||||
}
|
||||
|
||||
void ProgressMeterInterface::inc(int count UNUSED) {
|
||||
}
|
||||
|
||||
void ProgressMeterInterface::message(const std::string &mesg UNUSED, int level UNUSED) {
|
||||
}
|
||||
|
||||
} // namespace TPCE
|
||||
178
external/duckdb/third_party/tpce-tool/main/strutil.cpp
vendored
Normal file
178
external/duckdb/third_party/tpce-tool/main/strutil.cpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cerrno>
|
||||
#include <stdlib.h> // needed for strtoull which is not in the C++ headers
|
||||
|
||||
#include "utilities/EGenStandardTypes.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
using std::strtod;
|
||||
using std::strtoul;
|
||||
|
||||
namespace TPCE {
|
||||
|
||||
// Converts an ASCII string into a 64 bit integer. Accepts a scaling factor of
|
||||
// 'K', 'M', or 'G' on values.
|
||||
// ptr - string to convert
|
||||
// Returns the integral 64 bit representation
|
||||
INT64 strtoint64(const char *ptr) {
|
||||
INT64 val;
|
||||
char *endp;
|
||||
errno = 0;
|
||||
val = strtoull(ptr, &endp, 0);
|
||||
if (errno != 0) {
|
||||
std::ostringstream strm;
|
||||
strm << "Unable to parse integer '" << ptr << "'" << std::endl;
|
||||
throw std::runtime_error(strm.str());
|
||||
}
|
||||
switch (*endp) {
|
||||
case 'G':
|
||||
val *= 1000 * 1000 * 1000;
|
||||
break;
|
||||
case 'M':
|
||||
val *= 1000 * 1000;
|
||||
break;
|
||||
case 'K':
|
||||
val *= 1000;
|
||||
break;
|
||||
case '\0':
|
||||
endp--;
|
||||
break;
|
||||
default:
|
||||
std::ostringstream strm;
|
||||
strm << "Unable to parse invalid scale factor on integer '" << ptr << "'" << std::endl;
|
||||
throw std::runtime_error(strm.str());
|
||||
}
|
||||
if (*++endp != '\0') {
|
||||
std::ostringstream strm;
|
||||
strm << "Unable to parse trailing characters on integer '" << ptr << "'" << std::endl;
|
||||
throw std::runtime_error(strm.str());
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// Converts an ASCII string into a double. Accepts a scaling factor of
|
||||
// 'K', 'M', or 'G' on values.
|
||||
// ptr - string to convert
|
||||
// Returns the double representation
|
||||
double strtodbl(const char *ptr) {
|
||||
double val;
|
||||
char *endp;
|
||||
errno = 0;
|
||||
val = strtod(ptr, &endp);
|
||||
if (errno != 0) {
|
||||
std::ostringstream strm;
|
||||
strm << "Unable to parse floating point number '" << ptr << "'" << std::endl;
|
||||
throw std::runtime_error(strm.str());
|
||||
}
|
||||
switch (*endp) {
|
||||
case 'G':
|
||||
val *= 1000.0 * 1000.0 * 1000.0;
|
||||
break;
|
||||
case 'M':
|
||||
val *= 1000.0 * 1000.0;
|
||||
break;
|
||||
case 'K':
|
||||
val *= 1000.0;
|
||||
break;
|
||||
case '\0':
|
||||
endp--;
|
||||
break;
|
||||
default:
|
||||
std::ostringstream strm;
|
||||
strm << "Unable to parse invalid scale factor on floating point number '" << ptr << "'" << std::endl;
|
||||
throw std::runtime_error(strm.str());
|
||||
}
|
||||
if (*++endp != '\0') {
|
||||
std::ostringstream strm;
|
||||
strm << "Unable to parse trailing characters on floating point number '" << ptr << "'" << std::endl;
|
||||
throw std::runtime_error(strm.str());
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// Converts an ASCII string in "HH:MM:SS" form into a INT64. HH: or HH:MM:
|
||||
// may be omitted.
|
||||
// ptr - string to convert
|
||||
// Returns the 64 bit integer representation
|
||||
INT64 timestrtoint64(const char *ptr) {
|
||||
INT64 val;
|
||||
char *endp;
|
||||
errno = 0;
|
||||
val = strtoul(ptr, &endp, 0);
|
||||
if (*endp == ':') {
|
||||
val = val * 60 + strtoul(endp + 1, &endp, 0);
|
||||
if (*endp == ':') {
|
||||
val = val * 60 + strtoul(endp + 1, &endp, 0);
|
||||
}
|
||||
}
|
||||
if (errno != 0 || *endp != '\0') {
|
||||
std::ostringstream strm;
|
||||
strm << "Unable to parse time '" << ptr << "'" << std::endl;
|
||||
throw std::runtime_error(strm.str());
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// Converts a 64 bit integer into an HH:MM:SS string
|
||||
// val - integer to convert
|
||||
// Returns a string containing the formatted value.
|
||||
std::string int64totimestr(INT64 val) {
|
||||
std::ostringstream strm;
|
||||
int sec = static_cast<int>(val % 60);
|
||||
val /= 60;
|
||||
int min = static_cast<int>(val % 60);
|
||||
int hrs = static_cast<int>(val / 60);
|
||||
|
||||
strm << std::setfill('0');
|
||||
if (hrs) {
|
||||
strm << std::setw(2) << hrs << ":";
|
||||
}
|
||||
strm << std::setw(2) << min << ":" << std::setw(2) << sec;
|
||||
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
} // namespace TPCE
|
||||
Reference in New Issue
Block a user