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 * - Doug Johnson
35 */
36
37#include "input/DataFileManager.h"
38#include "input/tpce_flat_input.hpp"
39
40#include <assert.h>
41#include <stdexcept>
42
43//#include "utilities/MiscConsts.h"
44#include "input/TextFileSplitter.h"
45
46using namespace TPCE;
47
48// Centralized clean up of any allocated resources.
49void DataFileManager::CleanUp() {
50 // Clean up any/all data files.
51 if (areaCodeDataFile) {
52 delete areaCodeDataFile;
53 }
54 if (chargeDataFile) {
55 delete chargeDataFile;
56 }
57 if (commissionRateDataFile) {
58 delete commissionRateDataFile;
59 }
60 if (companyCompetitorDataFile) {
61 delete companyCompetitorDataFile;
62 }
63 if (companyDataFile) {
64 delete companyDataFile;
65 }
66 if (companySPRateDataFile) {
67 delete companySPRateDataFile;
68 }
69 if (exchangeDataFile) {
70 delete exchangeDataFile;
71 }
72 if (femaleFirstNameDataFile) {
73 delete femaleFirstNameDataFile;
74 }
75 if (industryDataFile) {
76 delete industryDataFile;
77 }
78 if (lastNameDataFile) {
79 delete lastNameDataFile;
80 }
81 if (maleFirstNameDataFile) {
82 delete maleFirstNameDataFile;
83 }
84 if (newsDataFile) {
85 delete newsDataFile;
86 }
87 if (nonTaxableAccountNameDataFile) {
88 delete nonTaxableAccountNameDataFile;
89 }
90 if (sectorDataFile) {
91 delete sectorDataFile;
92 }
93 if (securityDataFile) {
94 delete securityDataFile;
95 }
96 if (statusTypeDataFile) {
97 delete statusTypeDataFile;
98 }
99 if (streetNameDataFile) {
100 delete streetNameDataFile;
101 }
102 if (streetSuffixDataFile) {
103 delete streetSuffixDataFile;
104 }
105 if (taxableAccountNameDataFile) {
106 delete taxableAccountNameDataFile;
107 }
108 if (taxRateCountryDataFile) {
109 delete taxRateCountryDataFile;
110 }
111 if (taxRateDivisionDataFile) {
112 delete taxRateDivisionDataFile;
113 }
114 if (tradeTypeDataFile) {
115 delete tradeTypeDataFile;
116 }
117 if (zipCodeDataFile) {
118 delete zipCodeDataFile;
119 }
120
121 // Clean up any/all file abstractions.
122 if (companyCompetitorFile) {
123 delete companyCompetitorFile;
124 }
125 if (companyFile) {
126 delete companyFile;
127 }
128 if (securityFile) {
129 delete securityFile;
130 }
131 if (taxRateFile) {
132 delete taxRateFile;
133 }
134}
135
136DataFileManager::DataFileManager(TIdent configuredCustomerCount, TIdent activeCustomerCount)
137 : configuredCustomers(configuredCustomerCount), activeCustomers(activeCustomerCount), areaCodeDataFile(0),
138 chargeDataFile(0), commissionRateDataFile(0), companyCompetitorDataFile(0), companyDataFile(0),
139 companySPRateDataFile(0), exchangeDataFile(0), femaleFirstNameDataFile(0), industryDataFile(0),
140 lastNameDataFile(0), maleFirstNameDataFile(0), newsDataFile(0), nonTaxableAccountNameDataFile(0),
141 sectorDataFile(0), securityDataFile(0), statusTypeDataFile(0), streetNameDataFile(0), streetSuffixDataFile(0),
142 taxableAccountNameDataFile(0), taxRateCountryDataFile(0), taxRateDivisionDataFile(0), tradeTypeDataFile(0),
143 zipCodeDataFile(0), companyCompetitorFile(0), companyFile(0), securityFile(0), taxRateFile(0) {
144
145 // WARNING: This code is "brittle" since it is highly dependant on
146 // the enum definition.
147 for (int fileType = AREA_CODE_DATA_FILE; fileType <= ZIPCODE_DATA_FILE; ++fileType) {
148 loadFile((DataFileType)fileType);
149 }
150}
151
152DataFileManager::~DataFileManager() {
153 CleanUp();
154}
155
156// Load a file using an istream.
157void DataFileManager::loadFile(std::istream &source, DataFileType fileType) {
158 switch (fileType) {
159 case AREA_CODE_DATA_FILE:
160 loadFile<std::istream &, StreamSplitter, AreaCodeDataFile_t>(source, &areaCodeDataFile);
161 break;
162 case CHARGE_DATA_FILE:
163 loadFile<std::istream &, StreamSplitter, ChargeDataFile_t>(source, &chargeDataFile);
164 break;
165 case COMMISSION_RATE_DATA_FILE:
166 loadFile<std::istream &, StreamSplitter, CommissionRateDataFile_t>(source, &commissionRateDataFile);
167 break;
168 case COMPANY_COMPETITOR_DATA_FILE:
169 loadFile<std::istream &, StreamSplitter, CompanyCompetitorDataFile_t>(source, &companyCompetitorDataFile);
170 break;
171 case COMPANY_DATA_FILE:
172 loadFile<std::istream &, StreamSplitter, CompanyDataFile_t>(source, &companyDataFile);
173 break;
174 case COMPANY_SP_RATE_DATA_FILE:
175 loadFile<std::istream &, StreamSplitter, CompanySPRateDataFile_t>(source, &companySPRateDataFile);
176 break;
177 case EXCHANGE_DATA_FILE:
178 loadFile<std::istream &, StreamSplitter, ExchangeDataFile_t>(source, &exchangeDataFile);
179 break;
180 case FEMALE_FIRST_NAME_DATA_FILE:
181 loadFile<std::istream &, StreamSplitter, FemaleFirstNameDataFile_t>(source, &femaleFirstNameDataFile);
182 break;
183 case INDUSTRY_DATA_FILE:
184 loadFile<std::istream &, StreamSplitter, IndustryDataFile_t>(source, &industryDataFile);
185 break;
186 case LAST_NAME_DATA_FILE:
187 loadFile<std::istream &, StreamSplitter, LastNameDataFile_t>(source, &lastNameDataFile);
188 break;
189 case MALE_FIRST_NAME_DATA_FILE:
190 loadFile<std::istream &, StreamSplitter, MaleFirstNameDataFile_t>(source, &maleFirstNameDataFile);
191 break;
192 case NEWS_DATA_FILE:
193 loadFile<std::istream &, StreamSplitter, NewsDataFile_t>(source, &newsDataFile);
194 break;
195 case NON_TAXABLE_ACCOUNT_NAME_DATA_FILE:
196 loadFile<std::istream &, StreamSplitter, NonTaxableAccountNameDataFile_t>(source,
197 &nonTaxableAccountNameDataFile);
198 break;
199 case SECTOR_DATA_FILE:
200 loadFile<std::istream &, StreamSplitter, SectorDataFile_t>(source, &sectorDataFile);
201 break;
202 case SECURITY_DATA_FILE:
203 loadFile<std::istream &, StreamSplitter, SecurityDataFile_t>(source, &securityDataFile);
204 break;
205 case STATUS_TYPE_DATA_FILE:
206 loadFile<std::istream &, StreamSplitter, StatusTypeDataFile_t>(source, &statusTypeDataFile);
207 break;
208 case STREET_NAME_DATA_FILE:
209 loadFile<std::istream &, StreamSplitter, StreetNameDataFile_t>(source, &streetNameDataFile);
210 break;
211 case STREET_SUFFIX_DATA_FILE:
212 loadFile<std::istream &, StreamSplitter, StreetSuffixDataFile_t>(source, &streetSuffixDataFile);
213 break;
214 case TAXABLE_ACCOUNT_NAME_DATA_FILE:
215 loadFile<std::istream &, StreamSplitter, TaxableAccountNameDataFile_t>(source, &taxableAccountNameDataFile);
216 break;
217 case TAX_RATE_COUNTRY_DATA_FILE:
218 loadFile<std::istream &, StreamSplitter, TaxRateCountryDataFile_t>(source, &taxRateCountryDataFile);
219 break;
220 case TAX_RATE_DIVISION_DATA_FILE:
221 loadFile<std::istream &, StreamSplitter, TaxRateDivisionDataFile_t>(source, &taxRateDivisionDataFile);
222 break;
223 case TRADE_TYPE_DATA_FILE:
224 loadFile<std::istream &, StreamSplitter, TradeTypeDataFile_t>(source, &tradeTypeDataFile);
225 break;
226 case ZIPCODE_DATA_FILE:
227 loadFile<std::istream &, StreamSplitter, ZipCodeDataFile_t>(source, &zipCodeDataFile);
228 break;
229 default:
230 // Should never get here.
231 throw std::logic_error("Attempt to load by istream an unrecognized data file type.");
232 }
233}
234
235// Load a file using a file type.
236void DataFileManager::loadFile(DataFileType fileType) {
237 // Under the covers, call the pseudo-const overload.
238 const_cast<const DataFileManager *>(this)->loadFile(fileType);
239}
240
241// Helper method for lazy loading (hence logically const) by file type.
242void DataFileManager::loadFile(DataFileType fileType) const {
243 // Set up the appropriate file name.
244 switch (fileType) {
245 case AREA_CODE_DATA_FILE:
246 loadFile<std::string &, TextFileSplitter, AreaCodeDataFile_t>(AreaCodeConstantString, &areaCodeDataFile);
247 break;
248 case CHARGE_DATA_FILE:
249 loadFile<std::string &, TextFileSplitter, ChargeDataFile_t>(ChargeConstantString, &chargeDataFile);
250 break;
251 case COMMISSION_RATE_DATA_FILE:
252 loadFile<std::string &, TextFileSplitter, CommissionRateDataFile_t>(CommissionRateConstantString,
253 &commissionRateDataFile);
254 break;
255 case COMPANY_COMPETITOR_DATA_FILE:
256 loadFile<std::string &, TextFileSplitter, CompanyCompetitorDataFile_t>(CompanyCompetitorConstantString,
257 &companyCompetitorDataFile);
258 break;
259 case COMPANY_DATA_FILE:
260 loadFile<std::string &, TextFileSplitter, CompanyDataFile_t>(CompanyConstantString, &companyDataFile);
261 break;
262 case COMPANY_SP_RATE_DATA_FILE:
263 loadFile<std::string &, TextFileSplitter, CompanySPRateDataFile_t>(CompanySPRateConstantString,
264 &companySPRateDataFile);
265 break;
266 case EXCHANGE_DATA_FILE:
267 loadFile<std::string &, TextFileSplitter, ExchangeDataFile_t>(ExchangeConstantString, &exchangeDataFile);
268 break;
269 case FEMALE_FIRST_NAME_DATA_FILE:
270 loadFile<std::string &, TextFileSplitter, FemaleFirstNameDataFile_t>(FemaleFirstNameConstantString,
271 &femaleFirstNameDataFile);
272 break;
273 case INDUSTRY_DATA_FILE:
274 loadFile<std::string &, TextFileSplitter, IndustryDataFile_t>(IndustryConstantString, &industryDataFile);
275 break;
276 case LAST_NAME_DATA_FILE:
277 loadFile<std::string &, TextFileSplitter, LastNameDataFile_t>(LastNameConstantString, &lastNameDataFile);
278 break;
279 case MALE_FIRST_NAME_DATA_FILE:
280 loadFile<std::string &, TextFileSplitter, MaleFirstNameDataFile_t>(MaleFirstNameConstantString,
281 &maleFirstNameDataFile);
282 break;
283 case NEWS_DATA_FILE:
284 loadFile<std::string &, TextFileSplitter, NewsDataFile_t>(LastNameConstantString, &newsDataFile);
285 break;
286 case NON_TAXABLE_ACCOUNT_NAME_DATA_FILE:
287 loadFile<std::string &, TextFileSplitter, NonTaxableAccountNameDataFile_t>(NonTaxableAccountNameConstantString,
288 &nonTaxableAccountNameDataFile);
289 break;
290 case SECTOR_DATA_FILE:
291 loadFile<std::string &, TextFileSplitter, SectorDataFile_t>(SectorConstantString, &sectorDataFile);
292 break;
293 case SECURITY_DATA_FILE:
294 loadFile<std::string &, TextFileSplitter, SecurityDataFile_t>(SecurityConstantString, &securityDataFile);
295 break;
296 case STATUS_TYPE_DATA_FILE:
297 loadFile<std::string &, TextFileSplitter, StatusTypeDataFile_t>(StatusTypeConstantString, &statusTypeDataFile);
298 break;
299 case STREET_NAME_DATA_FILE:
300 loadFile<std::string &, TextFileSplitter, StreetNameDataFile_t>(StreetNameConstantString, &streetNameDataFile);
301 break;
302 case STREET_SUFFIX_DATA_FILE:
303 loadFile<std::string &, TextFileSplitter, StreetSuffixDataFile_t>(StreetSuffixConstantString,
304 &streetSuffixDataFile);
305 break;
306 case TAXABLE_ACCOUNT_NAME_DATA_FILE:
307 loadFile<std::string &, TextFileSplitter, TaxableAccountNameDataFile_t>(TaxableAccountNameConstantString,
308 &taxableAccountNameDataFile);
309 break;
310 case TAX_RATE_COUNTRY_DATA_FILE:
311 loadFile<std::string &, TextFileSplitter, TaxRateCountryDataFile_t>(TaxRatesCountryConstantString,
312 &taxRateCountryDataFile);
313 break;
314 case TAX_RATE_DIVISION_DATA_FILE:
315 loadFile<std::string &, TextFileSplitter, TaxRateDivisionDataFile_t>(TaxRatesDivisionConstantString,
316 &taxRateDivisionDataFile);
317 break;
318 case TRADE_TYPE_DATA_FILE:
319 loadFile<std::string &, TextFileSplitter, TradeTypeDataFile_t>(TradeTypeConstantString, &tradeTypeDataFile);
320 break;
321 case ZIPCODE_DATA_FILE:
322 loadFile<std::string &, TextFileSplitter, ZipCodeDataFile_t>(ZipCodeConstantString, &zipCodeDataFile);
323 break;
324 default:
325 // Should never get here.
326 assert(!"Attempt to load an unrecognized data file type.");
327 }
328}
329
330// Accessors for files.
331const AreaCodeDataFile_t &DataFileManager::AreaCodeDataFile() const {
332 if (!areaCodeDataFile) {
333 // Need to load the file.
334 loadFile(AREA_CODE_DATA_FILE);
335 }
336 return *areaCodeDataFile;
337}
338
339const ChargeDataFile_t &DataFileManager::ChargeDataFile() const {
340 if (!chargeDataFile) {
341 // Need to load the file.
342 loadFile(CHARGE_DATA_FILE);
343 }
344 return *chargeDataFile;
345}
346
347const CommissionRateDataFile_t &DataFileManager::CommissionRateDataFile() const {
348 if (!commissionRateDataFile) {
349 // Need to load the file.
350 loadFile(COMMISSION_RATE_DATA_FILE);
351 }
352 return *commissionRateDataFile;
353}
354
355const CompanyCompetitorDataFile_t &DataFileManager::CompanyCompetitorDataFile() const {
356 if (!companyCompetitorDataFile) {
357 // Need to load the file.
358 loadFile(COMPANY_COMPETITOR_DATA_FILE);
359 }
360 return *companyCompetitorDataFile;
361}
362
363const CompanyDataFile_t &DataFileManager::CompanyDataFile() const {
364 if (!companyDataFile) {
365 // Need to load the file.
366 loadFile(COMPANY_DATA_FILE);
367 }
368 return *companyDataFile;
369}
370
371const CompanySPRateDataFile_t &DataFileManager::CompanySPRateDataFile() const {
372 if (!companySPRateDataFile) {
373 // Need to load the file.
374 loadFile(COMPANY_SP_RATE_DATA_FILE);
375 }
376 return *companySPRateDataFile;
377}
378
379const ExchangeDataFile_t &DataFileManager::ExchangeDataFile() const {
380 if (!exchangeDataFile) {
381 // Need to load the file.
382 loadFile(EXCHANGE_DATA_FILE);
383 }
384 return *exchangeDataFile;
385}
386
387const FemaleFirstNameDataFile_t &DataFileManager::FemaleFirstNameDataFile() const {
388 if (!femaleFirstNameDataFile) {
389 // Need to load the file.
390 loadFile(FEMALE_FIRST_NAME_DATA_FILE);
391 }
392 return *femaleFirstNameDataFile;
393}
394
395const IndustryDataFile_t &DataFileManager::IndustryDataFile() const {
396 if (!industryDataFile) {
397 // Need to load the file.
398 loadFile(INDUSTRY_DATA_FILE);
399 }
400 return *industryDataFile;
401}
402
403const LastNameDataFile_t &DataFileManager::LastNameDataFile() const {
404 if (!lastNameDataFile) {
405 // Need to load the file.
406 loadFile(LAST_NAME_DATA_FILE);
407 }
408 return *lastNameDataFile;
409}
410
411const MaleFirstNameDataFile_t &DataFileManager::MaleFirstNameDataFile() const {
412 if (!maleFirstNameDataFile) {
413 // Need to load the file.
414 loadFile(MALE_FIRST_NAME_DATA_FILE);
415 }
416 return *maleFirstNameDataFile;
417}
418
419const NewsDataFile_t &DataFileManager::NewsDataFile() const {
420 if (!newsDataFile) {
421 // Need to load the file.
422 loadFile(NEWS_DATA_FILE);
423 }
424 return *newsDataFile;
425}
426
427const NonTaxableAccountNameDataFile_t &DataFileManager::NonTaxableAccountNameDataFile() const {
428 if (!nonTaxableAccountNameDataFile) {
429 // Need to load the file.
430 loadFile(NON_TAXABLE_ACCOUNT_NAME_DATA_FILE);
431 }
432 return *nonTaxableAccountNameDataFile;
433}
434
435const SectorDataFile_t &DataFileManager::SectorDataFile() const {
436 if (!sectorDataFile) {
437 // Need to load the file.
438 loadFile(SECTOR_DATA_FILE);
439 }
440 return *sectorDataFile;
441}
442
443const SecurityDataFile_t &DataFileManager::SecurityDataFile() const {
444 if (!securityDataFile) {
445 // Need to load the file.
446 loadFile(SECURITY_DATA_FILE);
447 }
448 return *securityDataFile;
449}
450
451const StatusTypeDataFile_t &DataFileManager::StatusTypeDataFile() const {
452 if (!statusTypeDataFile) {
453 // Need to load the file.
454 loadFile(STATUS_TYPE_DATA_FILE);
455 }
456 return *statusTypeDataFile;
457}
458
459const StreetNameDataFile_t &DataFileManager::StreetNameDataFile() const {
460 if (!streetNameDataFile) {
461 // Need to load the file.
462 loadFile(STREET_NAME_DATA_FILE);
463 }
464 return *streetNameDataFile;
465}
466
467const StreetSuffixDataFile_t &DataFileManager::StreetSuffixDataFile() const {
468 if (!streetSuffixDataFile) {
469 // Need to load the file.
470 loadFile(STREET_SUFFIX_DATA_FILE);
471 }
472 return *streetSuffixDataFile;
473}
474
475const TaxableAccountNameDataFile_t &DataFileManager::TaxableAccountNameDataFile() const {
476 if (!taxableAccountNameDataFile) {
477 // Need to load the file.
478 loadFile(TAXABLE_ACCOUNT_NAME_DATA_FILE);
479 }
480 return *taxableAccountNameDataFile;
481}
482
483const TaxRateCountryDataFile_t &DataFileManager::TaxRateCountryDataFile() const {
484 if (!taxRateCountryDataFile) {
485 // Need to load the file.
486 loadFile(TAX_RATE_COUNTRY_DATA_FILE);
487 }
488 return *taxRateCountryDataFile;
489}
490
491const TaxRateDivisionDataFile_t &DataFileManager::TaxRateDivisionDataFile() const {
492 if (!taxRateDivisionDataFile) {
493 // Need to load the file.
494 loadFile(TAX_RATE_DIVISION_DATA_FILE);
495 }
496 return *taxRateDivisionDataFile;
497}
498
499const TradeTypeDataFile_t &DataFileManager::TradeTypeDataFile() const {
500 if (!tradeTypeDataFile) {
501 // Need to load the file.
502 loadFile(TRADE_TYPE_DATA_FILE);
503 }
504 return *tradeTypeDataFile;
505}
506
507const ZipCodeDataFile_t &DataFileManager::ZipCodeDataFile() const {
508 if (!zipCodeDataFile) {
509 // Need to load the file.
510 loadFile(ZIPCODE_DATA_FILE);
511 }
512 return *zipCodeDataFile;
513}
514
515const CCompanyCompetitorFile &DataFileManager::CompanyCompetitorFile() const {
516 if (!companyCompetitorFile) {
517 // Need to create the "file". Fully qualify constructor to distinquish
518 // from this method.
519 companyCompetitorFile = new CCompanyCompetitorFile(CompanyCompetitorDataFile(), configuredCustomers,
520 activeCustomers, CompanyDataFile().size());
521 }
522 return *companyCompetitorFile;
523}
524
525const CCompanyFile &DataFileManager::CompanyFile() const {
526 if (!companyFile) {
527 // Need to create the "file". Fully qualify constructor to distinquish
528 // from this method.
529 companyFile = new CCompanyFile(CompanyDataFile(), configuredCustomers, activeCustomers);
530 }
531 return *companyFile;
532}
533
534const CSecurityFile &DataFileManager::SecurityFile() const {
535 if (!securityFile) {
536 // Need to create the "file". Fully qualify constructor to distinquish
537 // from this method.
538 securityFile =
539 new CSecurityFile(SecurityDataFile(), configuredCustomers, activeCustomers, CompanyDataFile().size());
540 }
541 return *securityFile;
542}
543
544const CTaxRateFile &DataFileManager::TaxRateFile() const {
545 if (!taxRateFile) {
546 // Need to create the "file". Fully qualify constructor to distinquish
547 // from this method.
548 taxRateFile = new CTaxRateFile(TaxRateCountryDataFile(), TaxRateDivisionDataFile());
549 }
550 return *taxRateFile;
551}
552