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
50namespace TPCE {
51
52const TIdent iBrokerNameIDShift = 1000 * 1000; // starting ID to generate names from for brokers
53
54const int iBrokerInitialTradesYTDMin = 10000;
55const int iBrokerInitialTradesYTDMax = 100000;
56
57const double fBrokerInitialCommissionYTDMin = 10000.0;
58const double fBrokerInitialCommissionYTDMax = 100000.0;
59
60class 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
69public:
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