Skip to content

Commit a6621e1

Browse files
authored
Merge pull request #6 from mobius1qwe/main
Ported project to delphi
2 parents 6309a1d + 430eb82 commit a6621e1

File tree

6 files changed

+1543
-106
lines changed

6 files changed

+1543
-106
lines changed

generator/Common/generate.common.pas

Lines changed: 95 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,18 @@
77
interface
88

99
uses
10-
Classes
11-
, SysUtils
12-
{$IFDEF FPC}
13-
{$ELSE}
14-
{$ENDIF}
15-
;
16-
17-
const
18-
cSeed: LongInt = 46668267; // '1BRC' in ASCII
19-
cColdestTemp = -99.9;
20-
cHottestTemp = 99.9;
10+
Classes, SysUtils, Math
11+
{$IFDEF FPC}
12+
, streamex, bufstream
13+
{$ELSE}
14+
, System.Diagnostics
15+
{$ENDIF}
16+
;
2117

2218
type
23-
{ TGenerator }
19+
20+
{ TGenerator }
21+
2422
TGenerator = class(TObject)
2523
private
2624
FInputFile: String;
@@ -29,10 +27,8 @@ TGenerator = class(TObject)
2927
FStationNames: TStringList;
3028

3129
procedure BuildStationNames;
32-
function GenerateProgressBar(
33-
APBPosition, APBMax, APBWIdth, AFileSize:Int64;
34-
ATimeElapsed: TDateTime
35-
):String;
30+
function GenerateProgressBar(APBPosition, APBMax, APBWIdth, AFileSize: Int64;
31+
ATimeElapsed: TDateTime): String;
3632
protected
3733
public
3834
constructor Create(AInputFile, AOutputFile: String; ALineCount: Int64);
@@ -42,42 +38,37 @@ TGenerator = class(TObject)
4238
published
4339
end;
4440

45-
implementation
41+
{$IFNDEF FPC}
42+
TStringArray = array of string;
43+
TWriteBufStream = TBufferedFileStream;
44+
{$ENDIF}
4645

47-
uses
48-
Math
49-
{$IFDEF FPC}
50-
, streamex
51-
, bufstream
52-
{$ELSE}
53-
, System.Diagnostics
54-
{$ENDIF}
55-
;
46+
implementation
5647

5748
const
49+
cSeed: LongInt = 46668267; // '1BRC' in ASCII
50+
cColdestTemp = -99.9;
51+
cHottestTemp = 99.9;
5852
linesPercent = 10;
5953
stationsCapacity = 50000;
6054
chunkBatch = 10000;
6155
chunkCapacity = 20 * 1024 * 1024;
6256
lineEnding = #13#10;
57+
lineBreak = #13;
6358

6459
{ TGenerator }
6560

66-
constructor TGenerator.Create(
67-
AInputFile,
68-
AOutputFile: String;
69-
ALineCount: Int64
70-
);
61+
constructor TGenerator.Create(AInputFile, AOutputFile: String; ALineCount: Int64);
7162
begin
72-
FInputFile:= AInputFile;
73-
FOutPutFile:= AOutputFile;
74-
FLineCount:= ALineCount;
63+
FInputFile := AInputFile;
64+
FOutPutFile := AOutputFile;
65+
FLineCount := ALineCount;
7566

76-
FStationNames:= TStringList.Create;
77-
FStationNames.Capacity:= stationsCapacity;
78-
FStationNames.UseLocale:= False;
79-
FStationNames.Duplicates:= dupIgnore;
80-
FStationNames.Sorted:= True;
67+
FStationNames := TStringList.Create;
68+
FStationNames.Capacity := stationsCapacity;
69+
FStationNames.UseLocale := False;
70+
FStationNames.Duplicates := dupIgnore;
71+
FStationNames.Sorted := True;
8172
end;
8273

8374
destructor TGenerator.Destroy;
@@ -91,36 +82,43 @@ procedure TGenerator.BuildStationNames;
9182
inputStream: TFileStream;
9283
streamReader: TStreamReader;
9384
entry: String;
94-
count: Int64 = 0;
85+
count: Int64;
9586
start, stop: Int64;
9687
begin
88+
count := 0; // cannot initialize vars in declaration (delphi complains)
9789
WriteLn('Building Weather Stations...');
9890
// Load the Weather Station names
9991
if FileExists(FInputFile) then
10092
begin
101-
inputStream:= TFileStream.Create(FInputFile, fmOpenRead);
93+
inputStream := TFileStream.Create(FInputFile, fmOpenRead);
10294
try
103-
streamReader:= TStreamReader.Create(inputStream);
95+
streamReader := TStreamReader.Create(inputStream);
10496
try
10597
{$IFDEF FPC}
106-
start:= GetTickCount64;
98+
start := GetTickCount64;
10799
while not streamReader.Eof do
100+
begin
101+
entry := streamReader.ReadLine;
102+
if entry[1] <> '#' then
103+
begin
104+
entry := entry.Split(';')[0];
105+
FStationNames.Add(entry);
106+
Inc(count);
107+
end;
108+
end;
109+
stop := GetTickCount64;
108110
{$ELSE}
109111
start := TStopwatch.GetTimeStamp;
110112
while not streamReader.EndOfStream do
111-
{$ENDIF}
112113
begin
113-
entry:= streamReader.ReadLine;
114+
entry := streamReader.ReadLine;
114115
if entry[1] <> '#' then
115116
begin
116-
entry:= entry.Split(';')[0];
117+
entry := entry.Split([';'])[0];
117118
FStationNames.Add(entry);
118119
Inc(count);
119120
end;
120121
end;
121-
{$IFDEF FPC}
122-
stop:= GetTickCount64;
123-
{$ELSE}
124122
stop := TStopwatch.GetTimeStamp;
125123
{$ENDIF}
126124
finally
@@ -132,35 +130,29 @@ procedure TGenerator.BuildStationNames;
132130
end
133131
else
134132
begin
135-
raise Exception.Create(Format('File "%s" not found.', [ FInputFile ]));
133+
raise Exception.Create(Format('File "%s" not found.', [FInputFile]));
136134
end;
137-
WriteLn(Format('Done: Processed %.n entries from a total of %.n weather stations in %d ms', [
138-
Double(count),
139-
Double(FStationNames.Count),
140-
stop-start
141-
]));
135+
WriteLn(Format
136+
('Done: Processed %.n entries from a total of %.n weather stations in %d ms',
137+
[Double(count), Double(FStationNames.count), stop - start]));
142138
WriteLn;
143139
end;
144140

145-
function TGenerator.GenerateProgressBar(
146-
APBPosition, APBMax, APBWIdth, AFileSize: Int64;
147-
ATimeElapsed: TDateTime
148-
): String;
141+
function TGenerator.GenerateProgressBar(APBPosition, APBMax, APBWIdth, AFileSize: Int64;
142+
ATimeElapsed: TDateTime): String;
149143
var
150144
percentDone: Double;
151145
filled: Integer;
152146
begin
153-
percentDone:= (100 * APBPosition) / APBMax;
154-
filled:= (APBWIdth * APBPosition ) div APBMax;
155-
Result:= '[';
156-
Result:= Result + StringOfChar('#', filled);
157-
Result:= Result + StringOfChar('-', APBWIdth - filled);
158-
Result:= Result + Format('] %5.2f %%', [ percentDone ]);
159-
Result:= Result + Format(' lines: %.n, file size: %.n, elapsed: %s ', [
160-
Double(APBPosition),
161-
Double(AFileSize),
162-
FormatDateTime('n" min, "s" sec"', ATimeElapsed)
163-
]);
147+
percentDone := (100 * APBPosition) / APBMax;
148+
filled := (APBWIdth * APBPosition) div APBMax;
149+
Result := '[';
150+
Result := Result + StringOfChar('#', filled);
151+
Result := Result + StringOfChar('-', APBWIdth - filled);
152+
Result := Result + Format('] %5.2f %%', [percentDone]);
153+
Result := Result + Format(' lines: %.n, file size: %.n, elapsed: %s ',
154+
[Double(APBPosition), Double(AFileSize), FormatDateTime('n" min, "s" sec"',
155+
ATimeElapsed)]);
164156
end;
165157

166158
procedure TGenerator.Generate;
@@ -178,20 +170,20 @@ procedure TGenerator.Generate;
178170
begin
179171
// Randomize sets this variable depending on the current time
180172
// We just set it to our own value
181-
RandSeed:= cSeed;
173+
RandSeed := cSeed;
182174

183175
// Build list of station names
184176
BuildStationNames;
185177

186-
outputFileStream:= TBufferedFileStream.Create(FOutPutFile, fmCreate);
178+
outputFileStream := TBufferedFileStream.Create(FOutPutFile, fmCreate);
187179

188-
progressBatch:= floor(FLineCount * (linesPercent / 100));
189-
start:= Now;
180+
progressBatch := floor(FLineCount * (linesPercent / 100));
181+
start := Now;
190182

191183
// This is all paweld magic:
192184
// From here
193-
//based on code @domasz from lazarus forum, github: PascalVault
194-
stationsCount := FStationNames.Count;
185+
// based on code @domasz from lazarus forum, github: PascalVault
186+
stationsCount := FStationNames.count;
195187
SetLength(stationArray, stationsCount);
196188
SetLength(LenStationArray, stationsCount);
197189
for index := 0 to stationsCount - 1 do
@@ -209,10 +201,15 @@ procedure TGenerator.Generate;
209201
begin
210202
randomTempStr := IntToStr(index);
211203
case Ord(randomTempStr[0]) of
212-
1: randomTempFinal := '0.' + randomTempStr;
213-
2: randomTempFinal := randomTempStr[1] + '.' + randomTempStr[2];
214-
3: randomTempFinal := randomTempStr[1] + randomTempStr[2] + '.' + randomTempStr[3];
215-
4: randomTempFinal := randomTempStr[1] + randomTempStr[2] + randomTempStr[3] + '.' + randomTempStr[4];
204+
1:
205+
randomTempFinal := '0.' + randomTempStr;
206+
2:
207+
randomTempFinal := randomTempStr[1] + '.' + randomTempStr[2];
208+
3:
209+
randomTempFinal := randomTempStr[1] + randomTempStr[2] + '.' + randomTempStr[3];
210+
4:
211+
randomTempFinal := randomTempStr[1] + randomTempStr[2] + randomTempStr[3] + '.' +
212+
randomTempStr[4];
216213
end;
217214
temperatureArray[index * 2 - 1] := randomTempFinal + lineEnding;
218215
LenTemperatureArray[index * 2 - 1] := Length(temperatureArray[index * 2 - 1]);
@@ -227,17 +224,19 @@ procedure TGenerator.Generate;
227224

228225
try
229226
// Print first state of the progress bar
230-
Write(GenerateProgressBar(1, FLineCount, 50, 0, Now - start), #13);
227+
Write(GenerateProgressBar(1, FLineCount, 50, 0, Now - start), lineBreak);
231228
// Generate the file
232-
for index:= 1 to FLineCount do
229+
for index := 1 to FLineCount do
233230
begin
234-
stationId:= Random(stationsCount);
231+
stationId := Random(stationsCount);
235232
// This is all paweld magic:
236233
// From here
237-
randomTemp:= Random(temperaturesCount);
238-
Move(stationArray[stationId][1], chunkLine[chunkLen + 1], LenStationArray[stationId]);
234+
randomTemp := Random(temperaturesCount);
235+
Move(stationArray[stationId][1], chunkLine[chunkLen + 1],
236+
LenStationArray[stationId]);
239237
Inc(chunkLen, LenStationArray[stationId]);
240-
Move(temperatureArray[randomTemp][1], chunkLine[chunkLen + 1], LenTemperatureArray[randomTemp]);
238+
Move(temperatureArray[randomTemp][1], chunkLine[chunkLen + 1],
239+
LenTemperatureArray[randomTemp]);
241240
Inc(chunkLen, LenTemperatureArray[randomTemp]);
242241

243242
Dec(chunkCount);
@@ -251,31 +250,28 @@ procedure TGenerator.Generate;
251250
Dec(progressBatch);
252251
if progressBatch = 0 then
253252
begin
254-
Write(GenerateProgressBar(
255-
index,
256-
FLineCount,
257-
50,
258-
outputFileStream.Size,
259-
Now - start
260-
), #13);
261-
progressBatch:= floor(FLineCount * (linesPercent / 100));
253+
Write(GenerateProgressBar(index, FLineCount, 50, outputFileStream.Size,
254+
Now - start), lineBreak);
255+
progressBatch := floor(FLineCount * (linesPercent / 100));
262256
end;
263257
end;
258+
264259
if chunkCount > 0 then
265260
begin
266261
outputFileStream.WriteBuffer(chunkLine[1], chunkLen);
262+
{$IFDEF FPC}
267263
outputFileStream.Flush;
264+
{$ELSE}
265+
outputFileStream.FlushBuffer;
266+
{$ENDIF}
268267
end;
269268
finally
270269
WriteLn;
271270
WriteLn;
272-
WriteLn(Format('Done: file size: %.n, elapsed: %s', [
273-
Double(outputFileStream.Size),
274-
FormatDateTime('n" min, "s" sec"', Now - start)
275-
]));
271+
WriteLn(Format('Done: file size: %.n, elapsed: %s', [Double(outputFileStream.Size),
272+
FormatDateTime('n" min, "s" sec"', Now - start)]));
276273
outputFileStream.Free;
277274
end;
278275
end;
279276

280277
end.
281-

generator/Common/generate.console.pas

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ interface
2020
cLongOptInput = 'input-file';
2121
cShortOptOutput: Char = 'o';
2222
cLongOptOutput = 'output-file';
23-
cShortOptNumner: Char = 'n';
23+
cShortOptNumber: Char = 'n';
2424
cLongOptNumber = 'line-count';
25-
25+
cShortOptions: array of char = ['h', 'v', 'i', 'o', 'n'];
26+
cLongOptions: array of string = ['help', 'version', 'input-file', 'output-file',
27+
'line-count'];
2628

2729
resourcestring
2830
rsAppTitle = 'One Billion Row Challenge Generator';

generator/Common/version.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
'0.3'
1+
const
2+
cVersion = '0.3';

0 commit comments

Comments
 (0)