Skip to content

Commit a9e08d1

Browse files
committed
feat: Generator complete
1 parent 432b8a3 commit a9e08d1

File tree

4 files changed

+247
-22
lines changed

4 files changed

+247
-22
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# 1BRC project specific
22
/bin
3+
/data/measurements.txt
34

45
# Compiled l10n files: .mo should be ignored
56
*.mo

generator/Common/generate.common.pas

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,149 @@
55
interface
66

77
uses
8-
Classes, SysUtils;
8+
Classes
9+
, SysUtils
10+
, streamex
11+
;
12+
13+
const
14+
cSeed: LongInt = 46668267; // '1BRC' in ASCII
15+
cColdestTemp = -99.9;
16+
cHottestTemp = 99.9;
17+
18+
type
19+
{ TGenerator }
20+
TGenerator = class(TObject)
21+
private
22+
FInputFile: String;
23+
FOutPutFile: String;
24+
FLineCount: Int64;
25+
FStationNames: TStringList;
26+
27+
procedure BuildStationNames;
28+
function GenerateProgressBar(APosition, AMax, ALength:Int64):String;
29+
protected
30+
public
31+
constructor Create(AInputFile, AOutputFile: String; ALineCount: Int64);
32+
destructor Destroy; override;
33+
34+
procedure Generate;
35+
published
36+
end;
937

1038
implementation
1139

40+
{ TGenerator }
41+
42+
constructor TGenerator.Create(
43+
AInputFile,
44+
AOutputFile: String;
45+
ALineCount: Int64
46+
);
47+
begin
48+
FInputFile:= AInputFile;
49+
FOutPutFile:= AOutputFile;
50+
FLineCount:= ALineCount;
51+
52+
FStationNames:= TStringList.Create;
53+
FStationNames.Duplicates:= dupIgnore;
54+
FStationNames.Sorted:= True;
55+
end;
56+
57+
destructor TGenerator.Destroy;
58+
begin
59+
FStationNames.Free;
60+
inherited Destroy;
61+
end;
62+
63+
procedure TGenerator.BuildStationNames;
64+
var
65+
inputStream: TFileStream;
66+
streamReader: TStreamReader;
67+
entry: String;
68+
count: Int64 = 0;
69+
begin
70+
//WriteLn('Reading "',FInputFile,'"');
71+
// Load the Weather Station names
72+
if FileExists(FInputFile) then
73+
begin
74+
inputStream:= TFileStream.Create(FInputFile, fmOpenRead);
75+
try
76+
streamReader:= TStreamReader.Create(inputStream);
77+
try
78+
while not streamReader.Eof do
79+
begin
80+
entry:= streamReader.ReadLine;
81+
if entry[1] <> '#' then
82+
begin
83+
entry:= entry.Split(';')[0];
84+
FStationNames.Add(entry);
85+
//WriteLn('Got: ', entry);
86+
Inc(count);
87+
end;
88+
end;
89+
finally
90+
streamReader.Free;
91+
end;
92+
finally
93+
inputStream.Free;
94+
end;
95+
end
96+
else
97+
begin
98+
raise Exception.Create(Format('File "%s" not found.', [ FInputFile ]));
99+
end;
100+
end;
101+
102+
function TGenerator.GenerateProgressBar(APosition, AMax, ALength: Int64
103+
): String;
104+
var
105+
percentDone: Double;
106+
filled: Integer;
107+
begin
108+
percentDone:= (100 * APosition) / AMax;
109+
filled:= (ALength * APosition ) div AMax;
110+
Result:= '[';
111+
Result:= Result + StringOfChar('#', filled);
112+
Result:= Result + StringOfChar('-', ALength - filled);
113+
Result:= Result + Format('] %5.2f %% done.', [ percentDone ]);
114+
end;
115+
116+
procedure TGenerator.Generate;
117+
var
118+
index: Int64;
119+
stationId: Int64;
120+
randomTemp: Double;
121+
outputStream: TFileStream;
122+
line: String;
123+
begin
124+
// Randomize sets this variable depending on the current time
125+
// We just set it to our own value
126+
RandSeed:= cSeed;
127+
128+
// Build list of station names
129+
BuildStationNames;
130+
131+
outputStream:= TFileStream.Create(FOutPutFile, fmCreate);
132+
try
133+
// Generate the file
134+
for index:= 1 to FLineCount do
135+
begin
136+
stationId:= Random(FStationNames.Count);
137+
randomTemp:= Random * (2 * cHottestTemp) - cHottestTemp;
138+
line:= Format('%s;%s'#13#10, [
139+
FStationNames[stationId],
140+
FormatFloat('#0.0', randomTemp)
141+
]);
142+
//Write(line);
143+
outputStream.WriteBuffer(line[1], Length(line));
144+
Write(GenerateProgressBar(index, FLineCount, 50), #13);
145+
end;
146+
finally
147+
outputStream.Free;
148+
end;
149+
WriteLn;
150+
end;
151+
12152
end.
13153

generator/Lazarus/src/generator.lpi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@
107107
<OtherUnitFiles Value="../../Common"/>
108108
<UnitOutputDirectory Value="../../../bin/lib/$(TargetCPU)-$(TargetOS)"/>
109109
</SearchPaths>
110+
<Linking>
111+
<Debugging>
112+
<DebugInfoType Value="dsDwarf3"/>
113+
</Debugging>
114+
</Linking>
110115
</CompilerOptions>
111116
<Debugging>
112117
<Exceptions Count="3">

generator/Lazarus/src/generator.lpr

Lines changed: 100 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,30 @@
1414

1515
const
1616
cVersion = {$I version.inc};
17-
cSeed: LongInt = 46668267; // '1BRC' in ASCII
18-
19-
cShortOptHelp = 'h';
20-
cLongOptHelp = 'help';
21-
cShortOptVersion = 'v';
22-
cLongOptVersion = 'version';
23-
cShortOptInput = 'i:';
24-
cLongOptInput = 'input-file:';
25-
cShortOptOutput = 'o:';
26-
cLongOptOutput = 'output-file:';
27-
cShortOptNumner = 'n:';
28-
cLongOptNumber = 'line-count:';
17+
18+
cShortOptHelp: Char = 'h';
19+
cLongOptHelp = 'help';
20+
cShortOptVersion: Char = 'v';
21+
cLongOptVersion = 'version';
22+
cShortOptInput: Char = 'i';
23+
cLongOptInput = 'input-file';
24+
cShortOptOutput: Char = 'o';
25+
cLongOptOutput = 'output-file';
26+
cShortOptNumner: Char = 'n';
27+
cLongOptNumber = 'line-count';
28+
29+
var
30+
inputFilename: String = '';
31+
outputFilename: String = '';
32+
lineCount: Int64 = 0;
2933

3034
type
3135

3236
{ TOneBRCGenerator }
3337

3438
TOneBRCGenerator = class(TCustomApplication)
3539
private
40+
FGenerator: TGenerator;
3641
protected
3742
procedure DoRun; override;
3843
public
@@ -47,9 +52,10 @@ TOneBRCGenerator = class(TCustomApplication)
4752
procedure TOneBRCGenerator.DoRun;
4853
var
4954
ErrorMsg: String;
55+
tmpLineCount: String;
5056
begin
5157
// quick check parameters
52-
ErrorMsg:= CheckOptions(Format('%s%s%s%s%s',[
58+
ErrorMsg:= CheckOptions(Format('%s%s%s:%s:%s:',[
5359
cShortOptHelp,
5460
cShortOptVersion,
5561
cShortOptInput,
@@ -59,32 +65,105 @@ procedure TOneBRCGenerator.DoRun;
5965
[
6066
cLongOptHelp,
6167
cLongOptVersion,
62-
cLongOptInput,
63-
cLongOptOutput,
64-
cLongOptNumber
68+
cLongOptInput+':',
69+
cLongOptOutput+':',
70+
cLongOptNumber+':'
6571
]
6672
);
67-
if ErrorMsg<>'' then begin
73+
if ErrorMsg<>'' then
74+
begin
6875
//ShowException(Exception.Create(ErrorMsg));
69-
WriteLn(ErrorMsg);
76+
WriteLn('ERROR: ', ErrorMsg);
7077
Terminate;
7178
Exit;
7279
end;
7380

7481
// parse parameters
75-
if HasOption(cShortOptHelp, cLongOptHelp) then begin
82+
if HasOption(cShortOptHelp, cLongOptHelp) then
83+
begin
7684
WriteHelp;
7785
Terminate;
7886
Exit;
7987
end;
8088

81-
if HasOption(cShortOptVersion, cLongOptVersion) then begin
89+
if HasOption(cShortOptVersion, cLongOptVersion) then
90+
begin
8291
WriteLn('generator v', cVersion);
8392
Terminate;
8493
Exit;
8594
end;
8695

87-
{ add your program here }
96+
if HasOption(cShortOptInput, cLongOptInput) then
97+
begin
98+
inputFilename:= GetOptionValue(
99+
cShortOptInput,
100+
cLongOptInput
101+
);
102+
end
103+
else
104+
begin
105+
WriteLn('ERROR: Missing input file flag');
106+
Terminate;
107+
Exit;
108+
end;
109+
110+
if HasOption(cShortOptOutput, cLongOptOutput) then
111+
begin
112+
outputFilename:= GetOptionValue(
113+
cShortOptOutput,
114+
cLongOptOutput
115+
);
116+
end
117+
else
118+
begin
119+
WriteLn('ERROR: Missing output file flag');
120+
Terminate;
121+
Exit;
122+
end;
123+
124+
if HasOption(cShortOptNumner, cLongOptNumber) then
125+
begin
126+
tmpLineCount:=GetOptionValue(
127+
cShortOptNumner,
128+
cLongOptNumber
129+
);
130+
tmpLineCount:= StringReplace(tmpLineCount, '_', '', [rfReplaceAll]);
131+
if not TryStrToInt64(tmpLineCount, lineCount) then
132+
begin
133+
WriteLn('ERROR: Invalid integer "',tmpLineCount,'"');
134+
Terminate;
135+
Exit;
136+
end;
137+
end
138+
else
139+
begin
140+
WriteLn('ERROR: Missing line count flag');
141+
Terminate;
142+
Exit;
143+
end;
144+
145+
146+
inputFilename:= ExpandFileName(inputFilename);
147+
outputFilename:= ExpandFileName(outputFilename);
148+
149+
WriteLn('Input File : ', inputFilename);
150+
WriteLn('Output File: ', outputFilename);
151+
WriteLn('Line Count : ', FormatFLoat('#'+DefaultFormatSettings.ThousandSeparator+'##0', lineCount));
152+
WriteLn;
153+
154+
FGenerator:= TGenerator.Create(inputFilename, outputFilename, lineCount);
155+
try
156+
try
157+
FGenerator.Generate;
158+
except
159+
on E: Exception do
160+
begin
161+
WriteLn('ERROR: ', E.Message);
162+
end;
163+
end;
164+
finally
165+
FGenerator.Free;
166+
end;
88167

89168
// stop program loop
90169
Terminate;

0 commit comments

Comments
 (0)