| 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 | * - Sergey Vasilevskiy | 
|---|
| 35 | * - Doug Johnson | 
|---|
| 36 | */ | 
|---|
| 37 |  | 
|---|
| 38 | /* | 
|---|
| 39 | *   Class representing the Brokers table. | 
|---|
| 40 | */ | 
|---|
| 41 | #ifndef BROKERS_H | 
|---|
| 42 | #define BROKERS_H | 
|---|
| 43 |  | 
|---|
| 44 | #include <stdio.h> // for snprintf which is not part of the C++ headers | 
|---|
| 45 | #include "EGenTables_common.h" | 
|---|
| 46 | #include "CustomerAccountsAndPermissionsTable.h" | 
|---|
| 47 | #include "input/DataFileManager.h" | 
|---|
| 48 | #include "StatusTypeIDs.h" | 
|---|
| 49 |  | 
|---|
| 50 | namespace TPCE { | 
|---|
| 51 |  | 
|---|
| 52 | const TIdent iBrokerNameIDShift = 1000 * 1000; // starting ID to generate names from for brokers | 
|---|
| 53 |  | 
|---|
| 54 | const int iBrokerInitialTradesYTDMin = 10000; | 
|---|
| 55 | const int iBrokerInitialTradesYTDMax = 100000; | 
|---|
| 56 |  | 
|---|
| 57 | const double fBrokerInitialCommissionYTDMin = 10000.0; | 
|---|
| 58 | const double fBrokerInitialCommissionYTDMax = 100000.0; | 
|---|
| 59 |  | 
|---|
| 60 | class CBrokersTable : public TableTemplate<BROKER_ROW> { | 
|---|
| 61 | TIdent m_iTotalBrokers; // total number of brokers rows to generate | 
|---|
| 62 | TIdent m_iStartFromBroker; | 
|---|
| 63 | TIdent m_iStartFromCustomer; | 
|---|
| 64 | CPerson m_person; | 
|---|
| 65 | const StatusTypeDataFile_t &m_StatusTypeFile; // STATUS_TYPE table from the flat file | 
|---|
| 66 | int *m_pNumTrades;                            // array of B_NUM_TRADES values | 
|---|
| 67 | double *m_pCommTotal;                         // array of B_COMM_TOTAL values | 
|---|
| 68 |  | 
|---|
| 69 | public: | 
|---|
| 70 | /* | 
|---|
| 71 | *  Constructor for the BROKER table class. | 
|---|
| 72 | * | 
|---|
| 73 | *  PARAMETERS: | 
|---|
| 74 | *       IN  inputFiles              - input flat files loaded in memory | 
|---|
| 75 | *       IN  iCustomerCount          - customer count | 
|---|
| 76 | *       IN  iStartFromCustomer      - starting customer id (1-based) | 
|---|
| 77 | * | 
|---|
| 78 | *  RETURNS: | 
|---|
| 79 | *       not applicable. | 
|---|
| 80 | */ | 
|---|
| 81 | CBrokersTable(const DataFileManager &dfm, TIdent iCustomerCount, TIdent iStartFromCustomer) | 
|---|
| 82 | : TableTemplate<BROKER_ROW>(), m_iTotalBrokers(iCustomerCount / iBrokersDiv), | 
|---|
| 83 | m_iStartFromBroker((iStartFromCustomer / iBrokersDiv) + iStartingBrokerID + iTIdentShift), | 
|---|
| 84 | m_iStartFromCustomer(iStartFromCustomer), m_person(dfm, iBrokerNameIDShift, true), | 
|---|
| 85 | m_StatusTypeFile(dfm.StatusTypeDataFile()), m_pNumTrades(NULL), m_pCommTotal(NULL){}; | 
|---|
| 86 |  | 
|---|
| 87 | /* | 
|---|
| 88 | *  Destructor. | 
|---|
| 89 | * | 
|---|
| 90 | *  PARAMETERS: | 
|---|
| 91 | *       not applicable. | 
|---|
| 92 | * | 
|---|
| 93 | *  RETURNS: | 
|---|
| 94 | *       not applicable. | 
|---|
| 95 | */ | 
|---|
| 96 | ~CBrokersTable() { | 
|---|
| 97 | if (m_pNumTrades != NULL) { | 
|---|
| 98 | delete[] m_pNumTrades; | 
|---|
| 99 | } | 
|---|
| 100 |  | 
|---|
| 101 | if (m_pCommTotal != NULL) { | 
|---|
| 102 | delete[] m_pCommTotal; | 
|---|
| 103 | } | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | /* | 
|---|
| 107 | *   Initialization method; required when generating data but not for | 
|---|
| 108 | * run-time. | 
|---|
| 109 | * | 
|---|
| 110 | *   It is called by CTradeGen at the beginning of every load unit. | 
|---|
| 111 | * | 
|---|
| 112 | *   PARAMETERS: | 
|---|
| 113 | *           IN  iCustomerCount      - new customer count | 
|---|
| 114 | *           IN  iStartFromCustomer  - new starting customer id (1-based) | 
|---|
| 115 | * | 
|---|
| 116 | *   RETURNS: | 
|---|
| 117 | *           none. | 
|---|
| 118 | */ | 
|---|
| 119 | void InitForGen(TIdent iCustomerCount, TIdent iStartFromCustomer) { | 
|---|
| 120 | TIdent i; | 
|---|
| 121 |  | 
|---|
| 122 | if (m_iTotalBrokers != iCustomerCount / iBrokersDiv || m_pNumTrades == NULL || m_pCommTotal == NULL) | 
|---|
| 123 |  | 
|---|
| 124 | { | 
|---|
| 125 | //  Reallocate arrays for the new number of brokers | 
|---|
| 126 | // | 
|---|
| 127 |  | 
|---|
| 128 | m_iTotalBrokers = iCustomerCount / iBrokersDiv; | 
|---|
| 129 |  | 
|---|
| 130 | if (m_pNumTrades != NULL) { | 
|---|
| 131 | delete[] m_pNumTrades; | 
|---|
| 132 | } | 
|---|
| 133 |  | 
|---|
| 134 | m_pNumTrades = new int[(size_t)m_iTotalBrokers]; | 
|---|
| 135 |  | 
|---|
| 136 | if (m_pCommTotal != NULL) { | 
|---|
| 137 | delete[] m_pCommTotal; | 
|---|
| 138 | } | 
|---|
| 139 |  | 
|---|
| 140 | m_pCommTotal = new double[(size_t)m_iTotalBrokers]; | 
|---|
| 141 | } | 
|---|
| 142 |  | 
|---|
| 143 | //  Initialize array to 0 | 
|---|
| 144 | // | 
|---|
| 145 | if (m_pNumTrades != NULL) { | 
|---|
| 146 | for (i = 0; i < m_iTotalBrokers; ++i) { | 
|---|
| 147 | m_pNumTrades[i] = 0; | 
|---|
| 148 | } | 
|---|
| 149 | } | 
|---|
| 150 |  | 
|---|
| 151 | //  Initialize array to 0 | 
|---|
| 152 | // | 
|---|
| 153 | if (m_pCommTotal != NULL) { | 
|---|
| 154 | for (i = 0; i < m_iTotalBrokers; ++i) { | 
|---|
| 155 | m_pCommTotal[i] = 0.0; | 
|---|
| 156 | } | 
|---|
| 157 | } | 
|---|
| 158 |  | 
|---|
| 159 | if (m_iStartFromBroker != ((iStartFromCustomer / iBrokersDiv) + iStartingBrokerID + iTIdentShift)) { | 
|---|
| 160 | // Multiplying by iBrokersDiv again to get 64-bit broker ids | 
|---|
| 161 | // with 4.3bln IDENT_T shift value. | 
|---|
| 162 | // Removing shift factor prior to arithmetic so that contiguous | 
|---|
| 163 | // B_IDs values are obtained, and then add it back so that we | 
|---|
| 164 | // get shifted values. | 
|---|
| 165 | // | 
|---|
| 166 | m_iStartFromBroker = (iStartFromCustomer / iBrokersDiv) + iStartingBrokerID + iTIdentShift; | 
|---|
| 167 | } | 
|---|
| 168 |  | 
|---|
| 169 | m_iLastRowNumber = 0; | 
|---|
| 170 |  | 
|---|
| 171 | ClearRecord(); // this is needed for EGenTest to work | 
|---|
| 172 |  | 
|---|
| 173 | // Don't re-initialize the cache for the first load unit | 
|---|
| 174 | if (m_iStartFromCustomer != iStartFromCustomer) { | 
|---|
| 175 | m_person.InitNextLoadUnit(iDefaultLoadUnitSize / iBrokersDiv); | 
|---|
| 176 | } | 
|---|
| 177 | }; | 
|---|
| 178 |  | 
|---|
| 179 | /* | 
|---|
| 180 | *   Increment year-to-date values for broker trades and commissions. | 
|---|
| 181 | *   Used to preserve consistency with initial trades. | 
|---|
| 182 | * | 
|---|
| 183 | *   PARAMETERS: | 
|---|
| 184 | *           IN  B_ID                    - broker for whom to update YTD | 
|---|
| 185 | * values IN  iTradeIncrement         - number of trades to add IN | 
|---|
| 186 | * fCommissionIncrement    - amount of commission to add | 
|---|
| 187 | * | 
|---|
| 188 | *   RETURNS: | 
|---|
| 189 | *           none. | 
|---|
| 190 | */ | 
|---|
| 191 | void UpdateTradeAndCommissionYTD(TIdent B_ID, int iTradeIncrement, double fCommissionIncrement) { | 
|---|
| 192 | if ((B_ID >= m_iStartFromBroker) && (B_ID < (m_iStartFromBroker + m_iTotalBrokers))) { | 
|---|
| 193 | m_pNumTrades[B_ID - m_iStartFromBroker] += iTradeIncrement; | 
|---|
| 194 | m_pCommTotal[B_ID - m_iStartFromBroker] += fCommissionIncrement; | 
|---|
| 195 | } | 
|---|
| 196 | } | 
|---|
| 197 |  | 
|---|
| 198 | /* | 
|---|
| 199 | *   Generate random broker id. | 
|---|
| 200 | *   Exposed mostly for the driver to ensure unique | 
|---|
| 201 | *   broker names for Broker Volume. | 
|---|
| 202 | *   External RNG object is used in order to honor CCE autoseed behavior. | 
|---|
| 203 | * | 
|---|
| 204 | *   PARAMETERS: | 
|---|
| 205 | *           IN  rnd             - external RNG | 
|---|
| 206 | * | 
|---|
| 207 | *   RETURNS: | 
|---|
| 208 | *           random broker id | 
|---|
| 209 | */ | 
|---|
| 210 | TIdent GenerateRandomBrokerId(CRandom *pRnd) { | 
|---|
| 211 | return pRnd->RndInt64Range(m_iStartFromBroker, m_iStartFromBroker + m_iTotalBrokers - 1); | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|
| 214 | /* | 
|---|
| 215 | *   Generate broker name into the provided buffer. | 
|---|
| 216 | *   Exposed mostly for the driver (Broker Volume). | 
|---|
| 217 | * | 
|---|
| 218 | *   PARAMETERS: | 
|---|
| 219 | *           IN  B_ID                - broker id | 
|---|
| 220 | *           IN  B_NAME              - buffer for broker name | 
|---|
| 221 | *           IN  B_NAME_len          - length of the name buffer | 
|---|
| 222 | * | 
|---|
| 223 | *   RETURNS: | 
|---|
| 224 | *           none. | 
|---|
| 225 | */ | 
|---|
| 226 | void GenerateBrokerName(TIdent B_ID, char *B_NAME, size_t B_NAME_len) { | 
|---|
| 227 | snprintf(B_NAME, B_NAME_len, "%s %c. %s", m_person.GetFirstName(B_ID + iBrokerNameIDShift).c_str(), | 
|---|
| 228 | m_person.GetMiddleName(B_ID + iBrokerNameIDShift), | 
|---|
| 229 | m_person.GetLastName(B_ID + iBrokerNameIDShift).c_str()); | 
|---|
| 230 | } | 
|---|
| 231 |  | 
|---|
| 232 | /* | 
|---|
| 233 | *   Return total broker count. | 
|---|
| 234 | *   Exposed mostly for the driver (Broker Volume). | 
|---|
| 235 | * | 
|---|
| 236 | *   PARAMETERS: | 
|---|
| 237 | *           none. | 
|---|
| 238 | * | 
|---|
| 239 | *   RETURNS: | 
|---|
| 240 | *           total number of brokers in the table | 
|---|
| 241 | */ | 
|---|
| 242 | TIdent GetBrokerCount() { | 
|---|
| 243 | return m_iTotalBrokers; | 
|---|
| 244 | } | 
|---|
| 245 |  | 
|---|
| 246 | /* | 
|---|
| 247 | *   Generates all column values for the next row | 
|---|
| 248 | *   and store them in the internal record structure. | 
|---|
| 249 | *   Increments the number of rows generated. | 
|---|
| 250 | * | 
|---|
| 251 | *   PARAMETERS: | 
|---|
| 252 | *           none. | 
|---|
| 253 | * | 
|---|
| 254 | *   RETURNS: | 
|---|
| 255 | *           TRUE, if there are more records in the ADDRESS table; FALSE | 
|---|
| 256 | * othewise. | 
|---|
| 257 | */ | 
|---|
| 258 | bool GenerateNextRecord() { | 
|---|
| 259 | m_row.B_ID = m_iStartFromBroker + m_iLastRowNumber; | 
|---|
| 260 | strncpy(m_row.B_ST_ID, m_StatusTypeFile[eActive].ST_ID_CSTR(), sizeof(m_row.B_ST_ID)); | 
|---|
| 261 |  | 
|---|
| 262 | GenerateBrokerName(m_row.B_ID, m_row.B_NAME, static_cast<int>(sizeof(m_row.B_NAME))); | 
|---|
| 263 |  | 
|---|
| 264 | m_row.B_NUM_TRADES = m_pNumTrades[m_row.B_ID - m_iStartFromBroker]; | 
|---|
| 265 | m_row.B_COMM_TOTAL = m_pCommTotal[m_row.B_ID - m_iStartFromBroker]; | 
|---|
| 266 |  | 
|---|
| 267 | // Update state info | 
|---|
| 268 | ++m_iLastRowNumber; | 
|---|
| 269 | m_bMoreRecords = m_iLastRowNumber < m_iTotalBrokers; | 
|---|
| 270 |  | 
|---|
| 271 | // Return false if all the rows have been generated | 
|---|
| 272 | return (MoreRecords()); | 
|---|
| 273 | } | 
|---|
| 274 | }; | 
|---|
| 275 |  | 
|---|
| 276 | } // namespace TPCE | 
|---|
| 277 |  | 
|---|
| 278 | #endif // BROKERS_H | 
|---|
| 279 |  | 
|---|