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 News Item and News XRef tables.
40 */
41#ifndef NEWS_ITEM_AND_XREG_TABLE_H
42#define NEWS_ITEM_AND_XREG_TABLE_H
43
44#include "EGenTables_common.h"
45#include "CompanyTable.h"
46
47#include "input/DataFileManager.h"
48
49namespace TPCE {
50
51const int iNewsItemsPerCompany = 2;
52const int iNewsItemMaxDaysAgo = 50; // how many days ago can a news item be dated
53
54const int iRNGSkipOneRowNews = 4 + cNI_ITEM_len; // number of RNG calls for one row
55
56typedef struct NEWS_ITEM_AND_XREF_ROW {
57 NEWS_ITEM_ROW news_item;
58 NEWS_XREF_ROW news_xref;
59} * PNEWS_ITEM_AND_XREF_ROW;
60
61class CNewsItemAndXRefTable : public TableTemplate<NEWS_ITEM_AND_XREF_ROW> {
62 CCompanyTable m_CompanyTable;
63 const NewsDataFile_t &m_News;
64 const LastNameDataFile_t &m_LastNames;
65 CDateTime m_NewsBaseDate;
66 int m_iNewsItemsGeneratedForCompany;
67 TIdent m_iNewsCountForOneLoadUnit;
68
69 void GenerateNewsItemHeadlineAndSummary(NEWS_ITEM_ROW &news_item) {
70 int iThreshold;
71 unsigned int iLen = 0;
72 const char *szWord;
73
74 while (iLen < sizeof(news_item.NI_ITEM) - 1) {
75 iThreshold = m_rnd.RndIntRange(0, m_News.size() - 1);
76
77 szWord = m_News[iThreshold].WORD_CSTR();
78
79 while (szWord && *szWord && (iLen < sizeof(news_item.NI_ITEM) - 1)) {
80 news_item.NI_ITEM[iLen++] = *szWord++; // copy one letter at a time
81 }
82
83 if (iLen < sizeof(news_item.NI_ITEM) - 1) {
84 news_item.NI_ITEM[iLen++] = ' '; // add space at the end of a word
85 }
86 }
87
88 news_item.NI_ITEM[iLen] = '\0'; // NULL terminate in case if the last
89 // word was copied only partially
90
91 // Now copy the headline and summary from the generated item.
92 memcpy(news_item.NI_HEADLINE, news_item.NI_ITEM, sizeof(news_item.NI_HEADLINE) - 1);
93 // news_item.NI_HEADLINE will be zero-terminated because it is
94 // initialized to all 0s in TableTemplate constructor and the last
95 // character is not overwritten.
96
97 // Now copy the headline and summary from the generated item.
98 memcpy(news_item.NI_SUMMARY, news_item.NI_ITEM, sizeof(news_item.NI_SUMMARY) - 1);
99 // news_item.NI_SUMMARY will be zero-terminated because it is
100 // initialized to all 0s in TableTemplate constructor and the last
101 // character is not overwritten.
102 }
103
104 /*
105 * Reset the state for the next load unit.
106 *
107 * PARAMETERS:
108 * none.
109 *
110 * RETURNS:
111 * none.
112 */
113 void InitNextLoadUnit() {
114 m_rnd.SetSeed(m_rnd.RndNthElement(RNGSeedTableDefault, (RNGSEED)m_iLastRowNumber * iRNGSkipOneRowNews));
115
116 ClearRecord(); // this is needed for EGenTest to work
117 }
118
119public:
120 CNewsItemAndXRefTable(const DataFileManager &dfm, TIdent iCustomerCount, TIdent iStartFromCustomer,
121 INT32 iHoursOfInitialTrades)
122 : m_CompanyTable(dfm, iCustomerCount, iStartFromCustomer), m_News(dfm.NewsDataFile()),
123 m_LastNames(dfm.LastNameDataFile()), m_iNewsItemsGeneratedForCompany(0) {
124 m_iLastRowNumber = iNewsItemsPerCompany * dfm.CompanyFile().CalculateStartFromCompany(iStartFromCustomer);
125
126 // Go to the last day of initial trades.
127 // News items will be dated up to iNewsItemMaxDaysAgo days back from
128 // that day.
129 //
130 m_NewsBaseDate.Set(InitialTradePopulationBaseYear, InitialTradePopulationBaseMonth,
131 InitialTradePopulationBaseDay, InitialTradePopulationBaseHour,
132 InitialTradePopulationBaseMinute, InitialTradePopulationBaseSecond,
133 InitialTradePopulationBaseFraction);
134 m_NewsBaseDate.Add(iHoursOfInitialTrades / HoursPerWorkDay, 0, true);
135
136 m_iNewsCountForOneLoadUnit =
137 dfm.CompanyFile().CalculateCompanyCount(iDefaultLoadUnitSize) * iNewsItemsPerCompany;
138 };
139
140 /*
141 * Generates all column values for the next row.
142 */
143 bool GenerateNextRecord() {
144 int iAddDayNo, iAddMSec, iThreshold;
145
146 // Reset RNG at Load Unit boundary, so that all data is repeatable.
147 //
148 if (m_iLastRowNumber % m_iNewsCountForOneLoadUnit == 0) {
149 InitNextLoadUnit();
150 }
151
152 // Generate NEWS_ITEM row
153 m_row.news_item.NI_ID = m_iLastRowNumber + 1; // row number starts from 0
154 GenerateNewsItemHeadlineAndSummary(m_row.news_item);
155 iAddDayNo = m_rnd.RndIntRange(0, iNewsItemMaxDaysAgo);
156 iAddMSec = m_rnd.RndIntRange(0, MsPerDay);
157 m_row.news_item.NI_DTS = m_NewsBaseDate; // substruct from the base date
158 m_row.news_item.NI_DTS.Add((-1) * iAddDayNo, (-1) * iAddMSec);
159
160 iThreshold = m_rnd.RndIntRange(0, m_LastNames.size() - 1);
161 strncpy(m_row.news_item.NI_AUTHOR, m_LastNames[iThreshold].NAME_CSTR(), sizeof(m_row.news_item.NI_AUTHOR));
162
163 iThreshold = m_rnd.RndIntRange(0, m_LastNames.size() - 1);
164 strncpy(m_row.news_item.NI_SOURCE, m_LastNames[iThreshold].NAME_CSTR(), sizeof(m_row.news_item.NI_SOURCE));
165
166 // Generate NEWS_XREF row
167 m_row.news_xref.NX_NI_ID = m_row.news_item.NI_ID;
168 m_row.news_xref.NX_CO_ID = m_CompanyTable.GetCurrentCO_ID();
169
170 ++m_iNewsItemsGeneratedForCompany;
171
172 ++m_iLastRowNumber;
173
174 if (m_iNewsItemsGeneratedForCompany >= iNewsItemsPerCompany) {
175 m_bMoreRecords = m_CompanyTable.GenerateNextCO_ID();
176 m_iNewsItemsGeneratedForCompany = 0;
177 } else {
178 m_bMoreRecords = true; // need to generate more rows for at least
179 // the current company
180 }
181
182 return (MoreRecords());
183 // return (m_iLastRowNumber < 10);
184 };
185
186 const NEWS_ITEM_ROW &GetNewsItemRow() {
187 return m_row.news_item;
188 }
189 const NEWS_XREF_ROW &GetNewsXRefRow() {
190 return m_row.news_xref;
191 }
192};
193
194} // namespace TPCE
195
196#endif // NEWS_ITEM_AND_XREG_TABLE_H
197