| 1 | /* |
| 2 | * Legal Notice |
| 3 | * |
| 4 | * This document and associated source code (the "Work") is a part of a |
| 5 | * benchmark specification maintained by the TPC. |
| 6 | * |
| 7 | * The TPC reserves all right, title, and interest to the Work as provided |
| 8 | * under U.S. and international laws, including without limitation all patent |
| 9 | * and trademark rights therein. |
| 10 | * |
| 11 | * No Warranty |
| 12 | * |
| 13 | * 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION |
| 14 | * CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE |
| 15 | * AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER |
| 16 | * WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY, |
| 17 | * INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES, |
| 18 | * DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR |
| 19 | * PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF |
| 20 | * WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE. |
| 21 | * ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, |
| 22 | * QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT |
| 23 | * WITH REGARD TO THE WORK. |
| 24 | * 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO |
| 25 | * ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE |
| 26 | * COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS |
| 27 | * OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT, |
| 28 | * INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY, |
| 29 | * OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT |
| 30 | * RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD |
| 31 | * ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. |
| 32 | * |
| 33 | * Contributors |
| 34 | * - Gregory Dake, Cecil Reames, Doug Johnson, Matt Emmerton |
| 35 | */ |
| 36 | |
| 37 | /****************************************************************************** |
| 38 | * Description: Implementation of CTxnGeneration class. |
| 39 | * See TxnMixGenerator.h for description. |
| 40 | ******************************************************************************/ |
| 41 | |
| 42 | #include "main/CETxnMixGenerator.h" |
| 43 | |
| 44 | using namespace TPCE; |
| 45 | |
| 46 | CCETxnMixGenerator::CCETxnMixGenerator(const PDriverCETxnSettings pDriverCETxnSettings, CBaseLogger *pLogger) |
| 47 | : m_pDriverCETxnSettings(pDriverCETxnSettings), m_rnd(RNGSeedBaseTxnMixGenerator) // initialize with default seed |
| 48 | , |
| 49 | m_pLogger(pLogger), m_iTxnArrayCurrentIndex(0), m_pTxnArray(NULL) { |
| 50 | // UpdateTunables() is called from CCE constructor (Initialize) |
| 51 | } |
| 52 | |
| 53 | CCETxnMixGenerator::CCETxnMixGenerator(const PDriverCETxnSettings pDriverCETxnSettings, RNGSEED RNGSeed, |
| 54 | CBaseLogger *pLogger) |
| 55 | : m_pDriverCETxnSettings(pDriverCETxnSettings), m_rnd(RNGSeed) // seed is provided for us |
| 56 | , |
| 57 | m_pLogger(pLogger), m_iTxnArrayCurrentIndex(0), m_pTxnArray(NULL) { |
| 58 | // UpdateTunables() is called from CCE constructor (Initialize) |
| 59 | } |
| 60 | |
| 61 | RNGSEED CCETxnMixGenerator::GetRNGSeed(void) { |
| 62 | return (m_rnd.GetSeed()); |
| 63 | } |
| 64 | |
| 65 | void CCETxnMixGenerator::SetRNGSeed(RNGSEED RNGSeed) { |
| 66 | m_rnd.SetSeed(RNGSeed); |
| 67 | } |
| 68 | |
| 69 | CCETxnMixGenerator::~CCETxnMixGenerator() { |
| 70 | if (m_pTxnArray != NULL) { |
| 71 | delete[] m_pTxnArray; |
| 72 | m_pTxnArray = NULL; |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | void CCETxnMixGenerator::UpdateTunables(void) { |
| 77 | INT32 i; |
| 78 | INT32 BrokerVolumeMixLimit; |
| 79 | INT32 CustomerPositionMixLimit; |
| 80 | INT32 MarketWatchMixLimit; |
| 81 | INT32 SecurityDetailMixLimit; |
| 82 | INT32 TradeLookupMixLimit; |
| 83 | INT32 TradeOrderMixLimit; |
| 84 | INT32 TradeStatusMixLimit; |
| 85 | INT32 TradeUpdateMixLimit; |
| 86 | |
| 87 | // Add all the weights together |
| 88 | m_CETransactionMixTotal = m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.BrokerVolumeMixLevel + |
| 89 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.CustomerPositionMixLevel + |
| 90 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.MarketWatchMixLevel + |
| 91 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.SecurityDetailMixLevel + |
| 92 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeLookupMixLevel + |
| 93 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeOrderMixLevel + |
| 94 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeStatusMixLevel + |
| 95 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeUpdateMixLevel; |
| 96 | |
| 97 | TradeStatusMixLimit = m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeStatusMixLevel; |
| 98 | MarketWatchMixLimit = |
| 99 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.MarketWatchMixLevel + TradeStatusMixLimit; |
| 100 | SecurityDetailMixLimit = |
| 101 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.SecurityDetailMixLevel + MarketWatchMixLimit; |
| 102 | CustomerPositionMixLimit = |
| 103 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.CustomerPositionMixLevel + SecurityDetailMixLimit; |
| 104 | TradeOrderMixLimit = |
| 105 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeOrderMixLevel + CustomerPositionMixLimit; |
| 106 | TradeLookupMixLimit = m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeLookupMixLevel + TradeOrderMixLimit; |
| 107 | TradeUpdateMixLimit = |
| 108 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.TradeUpdateMixLevel + TradeLookupMixLimit; |
| 109 | BrokerVolumeMixLimit = |
| 110 | m_pDriverCETxnSettings->TxnMixGenerator_settings.cur.BrokerVolumeMixLevel + TradeUpdateMixLimit; |
| 111 | |
| 112 | // Reset the random transaction array. |
| 113 | // |
| 114 | if (m_pTxnArray != NULL) { |
| 115 | delete[] m_pTxnArray; |
| 116 | m_pTxnArray = NULL; |
| 117 | } |
| 118 | |
| 119 | m_pTxnArray = new char[m_CETransactionMixTotal]; |
| 120 | |
| 121 | // Initialize the array with transaction types. |
| 122 | // |
| 123 | for (i = 0; i < TradeStatusMixLimit; ++i) { |
| 124 | m_pTxnArray[i] = TRADE_STATUS; |
| 125 | } |
| 126 | for (; i < MarketWatchMixLimit; ++i) { |
| 127 | m_pTxnArray[i] = MARKET_WATCH; |
| 128 | } |
| 129 | for (; i < SecurityDetailMixLimit; ++i) { |
| 130 | m_pTxnArray[i] = SECURITY_DETAIL; |
| 131 | } |
| 132 | for (; i < CustomerPositionMixLimit; ++i) { |
| 133 | m_pTxnArray[i] = CUSTOMER_POSITION; |
| 134 | } |
| 135 | for (; i < TradeOrderMixLimit; ++i) { |
| 136 | m_pTxnArray[i] = TRADE_ORDER; |
| 137 | } |
| 138 | for (; i < TradeLookupMixLimit; ++i) { |
| 139 | m_pTxnArray[i] = TRADE_LOOKUP; |
| 140 | } |
| 141 | for (; i < TradeUpdateMixLimit; ++i) { |
| 142 | m_pTxnArray[i] = TRADE_UPDATE; |
| 143 | } |
| 144 | for (; i < BrokerVolumeMixLimit; ++i) { |
| 145 | m_pTxnArray[i] = BROKER_VOLUME; |
| 146 | } |
| 147 | |
| 148 | m_iTxnArrayCurrentIndex = 0; // reset the current element index |
| 149 | |
| 150 | // Log Tunables |
| 151 | m_pLogger->SendToLogger(m_pDriverCETxnSettings->TxnMixGenerator_settings); |
| 152 | } |
| 153 | |
| 154 | int CCETxnMixGenerator::GenerateNextTxnType() { |
| 155 | // Select the next transaction type using the "card deck shuffle" |
| 156 | // algorithm (also Knuth algorithm) that guarantees a certain number |
| 157 | // of transactions of each type is returned. |
| 158 | // |
| 159 | // 1) Get a 32-bit random number. |
| 160 | // 2) Use random number to select next transaction type from m_pTxnArray |
| 161 | // in the range [m_iTxnArrayCurrentIndex, m_CETransactionMixTotal). |
| 162 | // 3) Swap the selected random element in m_pTxnArray |
| 163 | // with m_pTxnArray[m_iTxnArrayCurrentIndex]. |
| 164 | // 4) Increment m_iTxnArrayCurrentIndex to remove the returned |
| 165 | // transaction type from further consideration. |
| 166 | // |
| 167 | INT32 rnd = m_rnd.RndIntRange(m_iTxnArrayCurrentIndex, m_CETransactionMixTotal - 1); |
| 168 | |
| 169 | char iTxnType = m_pTxnArray[rnd]; |
| 170 | |
| 171 | // Swap two array entries. |
| 172 | // |
| 173 | m_pTxnArray[rnd] = m_pTxnArray[m_iTxnArrayCurrentIndex]; |
| 174 | m_pTxnArray[m_iTxnArrayCurrentIndex] = iTxnType; |
| 175 | |
| 176 | m_iTxnArrayCurrentIndex = (m_iTxnArrayCurrentIndex + 1) % m_CETransactionMixTotal; |
| 177 | |
| 178 | return iTxnType; |
| 179 | } |
| 180 | |