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 Company table. |
40 | */ |
41 | #ifndef COMPANY_TABLE_H |
42 | #define COMPANY_TABLE_H |
43 | |
44 | #include "EGenTables_common.h" |
45 | |
46 | #include "input/DataFileManager.h" |
47 | |
48 | namespace TPCE { |
49 | |
50 | const int iCEOMult = 1000; // for generating CEO name |
51 | |
52 | // Number of RNG calls to skip for one row in order |
53 | // to not use any of the random values from the previous row. |
54 | // |
55 | const int iRNGSkipOneRowCompany = 2; // one for SP rate and one for CO_OPEN_DATE |
56 | |
57 | class CCompanyTable : public TableTemplate<COMPANY_ROW> { |
58 | const CCompanyFile &m_CompanyFile; |
59 | const CompanySPRateDataFile_t &m_CompanySPRateFile; |
60 | CPerson m_person; // for CEO |
61 | CDateTime m_date; |
62 | TIdent m_iCO_AD_ID_START; // starting address id for companies |
63 | int m_iJan1_1800_DayNo; |
64 | int m_iJan2_2000_DayNo; |
65 | int m_iCurrentDayNo; |
66 | TIdent m_iCompanyCountForOneLoadUnit; |
67 | TIdent m_iCompanyCount; |
68 | TIdent m_iStartFromCompany; |
69 | |
70 | /* |
71 | * Generate distribution for the company inside S&P Rating file. |
72 | * |
73 | * PARAMETERS: |
74 | * none. |
75 | * |
76 | * RETURNS: |
77 | * threshold in the set of S&P credit ratings. |
78 | */ |
79 | int GetCompanySPRateThreshold() { |
80 | RNGSEED OldSeed; |
81 | int iCompanySPRateThreshold; |
82 | |
83 | OldSeed = m_rnd.GetSeed(); |
84 | m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedBaseSPRate, (RNGSEED)m_row.CO_ID)); |
85 | iCompanySPRateThreshold = m_rnd.RndIntRange(0, m_CompanySPRateFile.size() - 1); |
86 | m_rnd.SetSeed(OldSeed); |
87 | return (iCompanySPRateThreshold); |
88 | } |
89 | |
90 | /* |
91 | * S&P Credit Rating for the current company. |
92 | * It is stored in the current record structure. |
93 | * |
94 | * PARAMETERS: |
95 | * none. |
96 | * |
97 | * RETURNS: |
98 | * none. |
99 | */ |
100 | void GenerateCompanySPRate(void) { |
101 | int iThreshold = GetCompanySPRateThreshold(); |
102 | |
103 | // Select the row in the input file |
104 | strncpy(m_row.CO_SP_RATE, m_CompanySPRateFile[iThreshold].CO_SP_RATE_CSTR(), sizeof(m_row.CO_SP_RATE)); |
105 | } |
106 | |
107 | /* |
108 | * Reset the state for the next load unit. |
109 | * |
110 | * PARAMETERS: |
111 | * none. |
112 | * |
113 | * RETURNS: |
114 | * none. |
115 | */ |
116 | void InitNextLoadUnit() { |
117 | m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedTableDefault, (RNGSEED)m_iLastRowNumber * iRNGSkipOneRowCompany)); |
118 | |
119 | ClearRecord(); // this is needed for EGenTest to work |
120 | } |
121 | |
122 | public: |
123 | /* |
124 | * Constructor. |
125 | * |
126 | * PARAMETERS: |
127 | * IN inputFiles - input flat files loaded in memory |
128 | * IN iCustomerCount - number of customers to generate |
129 | * IN iStartFromCustomer - ordinal position of the first |
130 | * customer in the sequence (Note: 1-based) |
131 | * |
132 | * RETURNS: |
133 | * not applicable. |
134 | */ |
135 | CCompanyTable(const DataFileManager &dfm, TIdent iCustomerCount, TIdent iStartFromCustomer) |
136 | : TableTemplate<COMPANY_ROW>(), m_CompanyFile(dfm.CompanyFile()), |
137 | m_CompanySPRateFile(dfm.CompanySPRateDataFile()), m_person(dfm, 0, false) { |
138 | m_iJan1_1800_DayNo = CDateTime::YMDtoDayno(1800, 1, 1); // days number for Jan 1, 1800 |
139 | m_iJan2_2000_DayNo = CDateTime::YMDtoDayno(2000, 1, 2); // days number for Jan 2, 2000 |
140 | m_iCurrentDayNo = m_date.DayNo(); // today's days number |
141 | |
142 | m_iCompanyCountForOneLoadUnit = m_CompanyFile.CalculateCompanyCount(iDefaultLoadUnitSize); |
143 | |
144 | m_iCompanyCount = m_CompanyFile.CalculateCompanyCount(iCustomerCount); |
145 | m_iStartFromCompany = m_CompanyFile.CalculateStartFromCompany(iStartFromCustomer); |
146 | |
147 | m_iLastRowNumber = m_iStartFromCompany; |
148 | // Start Company addresses immediately after Exchange addresses, |
149 | // and company addresses for prior companies |
150 | m_iCO_AD_ID_START = dfm.ExchangeDataFile().size() + m_iStartFromCompany + iTIdentShift; |
151 | }; |
152 | |
153 | /* |
154 | * Generate and store state information for the next CO_ID. |
155 | * The number of rows generated is incremented. This is why |
156 | * this function cannot be called more than once for a record. |
157 | * |
158 | * PARAMETERS: |
159 | * none. |
160 | * |
161 | * RETURNS: |
162 | * TRUE, if there are more company ids to generate; FALSE, otherwise. |
163 | */ |
164 | bool GenerateNextCO_ID() { |
165 | ++m_iLastRowNumber; |
166 | m_bMoreRecords = m_iLastRowNumber < (m_iStartFromCompany + m_iCompanyCount); |
167 | |
168 | return (MoreRecords()); |
169 | } |
170 | |
171 | /* |
172 | * Return the current CO_ID. Since it doesn't generate the next CO_ID, |
173 | * this function can be called many times for the same record. |
174 | * |
175 | * PARAMETERS: |
176 | * none. |
177 | * |
178 | * RETURNS: |
179 | * CO_ID in the current record. |
180 | */ |
181 | TIdent GetCurrentCO_ID() { |
182 | return (m_CompanyFile.GetCompanyId(m_iLastRowNumber)); |
183 | } |
184 | |
185 | /* |
186 | * Generate all column values for the next row |
187 | * and store them in the internal record structure. |
188 | * Increment the number of rows generated. |
189 | * |
190 | * PARAMETERS: |
191 | * none. |
192 | * |
193 | * RETURNS: |
194 | * TRUE, if there are more records in the ADDRESS table; FALSE |
195 | * othewise. |
196 | */ |
197 | bool GenerateNextRecord() { |
198 | int iFoundDayNo; |
199 | |
200 | // Reset RNG at Load Unit boundary, so that all data is repeatable. |
201 | // |
202 | if (m_iLastRowNumber % m_iCompanyCountForOneLoadUnit == 0) { |
203 | InitNextLoadUnit(); |
204 | } |
205 | |
206 | m_row.CO_ID = GetCurrentCO_ID(); |
207 | |
208 | strncpy(m_row.CO_ST_ID, m_CompanyFile.GetRecord(m_iLastRowNumber).CO_ST_ID_CSTR(), sizeof(m_row.CO_ST_ID)); |
209 | |
210 | m_CompanyFile.CreateName(m_iLastRowNumber, m_row.CO_NAME, static_cast<int>(sizeof(m_row.CO_NAME))); |
211 | |
212 | strncpy(m_row.CO_IN_ID, m_CompanyFile.GetRecord(m_iLastRowNumber).CO_IN_ID_CSTR(), sizeof(m_row.CO_IN_ID)); |
213 | |
214 | GenerateCompanySPRate(); |
215 | |
216 | snprintf(m_row.CO_CEO, sizeof(m_row.CO_CEO), "%s %s" , m_person.GetFirstName(iCEOMult * m_row.CO_ID).c_str(), |
217 | m_person.GetLastName(iCEOMult * m_row.CO_ID).c_str()); |
218 | |
219 | strncpy(m_row.CO_DESC, m_CompanyFile.GetRecord(m_iLastRowNumber).CO_DESC_CSTR(), sizeof(m_row.CO_DESC)); |
220 | |
221 | m_row.CO_AD_ID = ++m_iCO_AD_ID_START; |
222 | |
223 | iFoundDayNo = m_rnd.RndIntRange(m_iJan1_1800_DayNo, m_iJan2_2000_DayNo); |
224 | |
225 | m_row.CO_OPEN_DATE.Set(iFoundDayNo); |
226 | |
227 | // Update state info |
228 | return GenerateNextCO_ID(); |
229 | } |
230 | }; |
231 | |
232 | } // namespace TPCE |
233 | |
234 | #endif // COMPANY_TABLE_H |
235 | |