Skip to content

Commit 9f83b70

Browse files
committed
refactor: Getting ready for baseline Common
1 parent 334922f commit 9f83b70

5 files changed

Lines changed: 289 additions & 207 deletions

File tree

baseline/Common/baseline.common.pas

Lines changed: 12 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -9,217 +9,32 @@ interface
99
uses
1010
Classes
1111
, SysUtils
12-
{$IFDEF FPC}
13-
, Contnrs
14-
{$ELSE}
15-
{$ENDIF}
16-
1712
;
1813

19-
type
20-
{ TWeatherStation }
21-
PWeatherStation = ^TWeatherStation;
22-
TWeatherStation = record
23-
FStation: String[100];
24-
FMin: Int64;
25-
FMax: Int64;
26-
FTot: Int64;
27-
FCnt: Integer;
28-
29-
end;
30-
{ TBaseline }
31-
TBaseline = class(TObject)
32-
private
33-
FInputFile: String;
34-
FStationNames: TStringList;
35-
FHashStationList: TFPHashList;
36-
procedure AddToHashList(AStation: String; ATemp: Int64);
37-
procedure BuildHashList;
38-
function RoundEx(x: Currency): Double;
39-
protected
40-
public
41-
constructor Create(AInputFile: String);
42-
destructor Destroy; override;
43-
44-
procedure Generate;
45-
published
46-
end;
47-
48-
{$IFNDEF FPC}
49-
TStringArray = array of Utf8String;
50-
TWriteBufStream = TFileStream;
51-
{$ENDIF}
14+
function RoundExDouble(const ATemp: Double): Double;
15+
function RoundExInteger(const ATemp: Double): Integer;
5216

5317
implementation
5418

55-
uses
56-
Math
57-
{$IFDEF FPC}
58-
, streamex
59-
{$ELSE}
60-
, System.Diagnostics
61-
{$IF defined(MSWINDOWS)}, Winapi.Windows{$ENDIF}
62-
{$ENDIF}
63-
;
64-
65-
const
66-
//lineEnding = #13#10;
67-
stationsCapacity = 50000;
68-
69-
70-
function Compare(AList: TStringList; AIndex1, AIndex2: Integer): Integer;
71-
var
72-
Pos1, Pos2: Integer;
73-
Str1, Str2: String;
74-
begin
75-
Result := 0;
76-
Str1 := AList.Strings[AIndex1];
77-
Str2 := AList.Strings[AIndex2];
78-
Pos1 := Pos('=', Str1);
79-
Pos2 := Pos('=', Str2);
80-
if (Pos1 > 0) and (Pos2 > 0) then
81-
begin
82-
Str1 := Copy(Str1, 1, Pos1 - 1);
83-
Str2 := Copy(Str2, 1, Pos2 - 1);
84-
Result := CompareStr(Str1, Str2);
85-
end;
86-
end;
87-
88-
{ TBaseline }
89-
90-
constructor TBaseline.Create(AInputFile: String);
91-
begin
92-
FInputFile := AInputFile;
93-
94-
FHashStationList:= TFPHashList.Create;
95-
FHashStationList.Capacity:= stationsCapacity;
96-
97-
FStationNames := TStringList.Create;
98-
FStationNames.Capacity := stationsCapacity;
99-
FStationNames.UseLocale := False;
100-
end;
101-
102-
destructor TBaseline.Destroy;
103-
var
104-
index: Integer;
105-
begin
106-
FStationNames.Free;
107-
for index:= 0 to FHashStationList.Count - 1 do
108-
begin
109-
Dispose(PWeatherStation(FHashStationList.Items[index]));
110-
end;
111-
FHashStationList.Free;
112-
inherited Destroy;
113-
end;
114-
115-
procedure TBaseline.AddToHashList(AStation: String; ATemp: Int64);
116-
var
117-
weatherStation: PWeatherStation;
118-
Index: Integer;
19+
function Ceiling(const ANumber: Double): integer;
11920
begin
120-
Index := FHashStationList.FindIndexOf(AStation);
121-
if Index = -1 then
122-
begin
123-
New(weatherStation);
124-
weatherStation^.FStation := AStation;
125-
weatherStation^.FMin := ATemp;
126-
weatherStation^.FMax := ATemp;
127-
weatherStation^.FTot := ATemp;
128-
weatherStation^.FCnt := 1;
129-
FHashStationList.Add(AStation, weatherStation);
130-
end
131-
else
132-
begin
133-
weatherStation := FHashStationList.Items[Index];
134-
weatherStation^.FMin := Min(weatherStation^.FMin, ATemp);
135-
weatherStation^.FMax := Max(weatherStation^.FMax, ATemp);
136-
weatherStation^.FTot := weatherStation^.FTot + ATemp;
137-
weatherStation^.FCnt := weatherStation^.FCnt + 1;
138-
end;
21+
Result := Trunc(ANumber) + Ord(Frac(ANumber) > 0);
13922
end;
14023

141-
procedure TBaseline.BuildHashList;
24+
function RoundExDouble(const ATemp: Double): Double;
14225
var
143-
inputFileStream: TFileStream;
144-
streamReader: TStreamReader;
145-
position, Code: Integer;
146-
strLine: String;
147-
strStation: String;
148-
strTemp: String;
149-
temparature: Int64;
150-
begin
151-
if FileExists(FInputFile) then
152-
begin
153-
inputFileStream:= TFileStream.Create(FInputFile, fmOpenRead);
154-
try
155-
streamReader:= TStreamReader.Create(inputFileStream);
156-
try
157-
while not streamReader.Eof do
158-
begin
159-
strLine:= streamReader.ReadLine;
160-
position := Pos(';', strLine);
161-
if position > 0 then
162-
begin
163-
strStation := Copy(strLine, 1, position - 1);
164-
strTemp := Copy(strLine, position + 1, Length(strLine));
165-
strTemp := StringReplace(strTemp, '.', '', [rfReplaceAll]);
166-
Val(strTemp, temparature, Code);
167-
if Code <> 0 then
168-
Continue;
169-
AddToHashList(strStation, temparature);
170-
end;
171-
end;
172-
finally
173-
streamReader.Free;
174-
end;
175-
finally
176-
inputFileStream.Free;
177-
end;
178-
end
179-
else
180-
begin
181-
raise Exception.Create(Format('File "%s" not found.', [FInputFile]));
182-
end;
183-
end;
184-
185-
function TBaseline.RoundEx(x: Currency): Double;
26+
tmp: Double;
18627
begin
187-
Result := Ceil(x * 10) / 10;
28+
tmp:= ATemp * 10;
29+
Result := Ceiling(tmp) / 10;
18830
end;
18931

190-
procedure TBaseline.Generate;
32+
function RoundExInteger(const ATemp: Double): Integer;
19133
var
192-
index: Integer;
193-
strTemp: String;
194-
min: Double;
195-
max: Double;
196-
mean: Double;
197-
weatherStation: PWeatherStation;
34+
tmp: Double;
19835
begin
199-
200-
BuildHashList;
201-
202-
FStationNames.BeginUpdate;
203-
for index := 0 to FHashStationList.Count - 1 do
204-
begin
205-
weatherStation := FHashStationList.Items[index];
206-
Min := RoundEx(weatherStation^.FMin/10);
207-
Max := RoundEx(weatherStation^.FMax/10);
208-
Mean := RoundEx(weatherStation^.FTot/weatherStation^.FCnt/10);
209-
strTemp := weatherStation^.FStation + '=' + FormatFloat('0.0', Min) + '/' + FormatFloat('0.0', Mean) + '/' + FormatFloat('0.0', Max) + ',';
210-
FStationNames.Add(strTemp);
211-
end;
212-
FStationNames.EndUpdate;
213-
FStationNames.CustomSort(@Compare);
214-
215-
strTemp:= '';
216-
for index:= 0 to FStationNames.Count - 1 do
217-
begin
218-
strTemp:= strTemp + FStationNames[index] + ' ';
219-
end;
220-
SetLength(strTemp, Length(strTemp) - 2);
221-
WriteLn('{', strTemp, '}');
222-
36+
tmp:= ATemp * 10;
37+
Result := Ceiling(tmp);
22338
end;
22439

22540
end.

baseline/Common/baseline.console.pas

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,44 @@ interface
1212
;
1313

1414
const
15+
{$IFDEF FPC}
1516
cShortOptHelp: Char = 'h';
1617
cLongOptHelp = 'help';
1718
cShortOptVersion: Char = 'v';
1819
cLongOptVersion = 'version';
1920
cShortOptInput: Char = 'i';
2021
cLongOptInput = 'input-file';
21-
{$IFNDEF FPC}
22-
cShortOptions: array of char = ['h', 'v'{, 'i', 'o', 'n'}];
23-
cLongOptions: array of string = ['help', 'version'{, 'input-file', 'output-file',
24-
'line-count'}];
22+
{$ELSE}
23+
cOptionHelp: array of string = ['-h', '--help'];
24+
cOptionVersion: array of string = ['-v', '--version'];
25+
cOptionInput: array of string = ['-i', '--input-file'];
2526
{$ENDIF}
2627

2728
resourcestring
28-
rsAppTitle = 'One Billion Row Challenge Baseline';
29+
rsAppTitle = 'One Billion Row Challenge Baseline';
2930
rsGeneratorVersion = 'baseline v%s';
30-
rsErrorMessage = 'ERROR: %s';
31+
rsErrorMessage = 'ERROR: %s';
3132
rsMissingInputFlag = 'Missing input file flag.';
33+
rsNoInputFile = 'File "%s" not found.';
3234

3335
var
3436
inputFilename: String = '';
35-
{outputFilename: String = '';
36-
lineCount: Integer = 0;}
3737

3838
procedure WriteHelp;
39+
{$IFNDEF FPC}
40+
function ParseCmdLineParams (out aInputFile: string): Boolean;
41+
{$ENDIF}
3942

4043

4144
implementation
4245

46+
{$IFNDEF FPC}
47+
uses
48+
System.IOUtils
49+
;
50+
{$ENDIF}
51+
52+
4353
procedure WriteHelp;
4454
begin
4555
WriteLn('Generates the output for the challenge');
@@ -53,5 +63,53 @@ procedure WriteHelp;
5363
WriteLn(' -i|--input-file <filename> The file containing the Weather Stations');
5464
end;
5565

66+
{$IFNDEF FPC}
67+
function ArrayContains (const aArray: array of string; const aValue: string): Boolean;
68+
var
69+
iValue: string;
70+
begin
71+
Result := False;
72+
for iValue in aArray do begin
73+
if aValue.ToLower = iValue then begin
74+
Result := True;
75+
break;
76+
end;
77+
end;
78+
end;
79+
80+
function ParseCmdLineParams (out aInputFile: string): Boolean;
81+
var
82+
I: Integer;
83+
begin
84+
Result := False;
85+
aInputFile := '';
86+
87+
// 0 is the exe path, so we start at 1
88+
for I := 1 to ParamCount do begin
89+
if ArrayContains (cOptionHelp, ParamStr(I)) then begin
90+
WriteHelp;
91+
exit;
92+
end
93+
else if ArrayContains (cOptionVersion, ParamStr(I)) then begin
94+
WriteLn(Format(rsGeneratorVersion, [ cVersion ]));
95+
exit;
96+
end
97+
else if ArrayContains (cOptionInput, ParamStr(I)) then begin
98+
// must be followed by the user's specified input file
99+
if (I+1) <= ParamCount then
100+
aInputFile := ExpandFileName (ParamStr (I+1));
101+
if not TFile.Exists (aInputFile) then
102+
WriteLn(Format(rsErrorMessage, [ Format(rsNoInputFile, [aInputFile]) ]))
103+
else begin
104+
Result := True;
105+
exit;
106+
end;
107+
end
108+
else
109+
WriteLn(Format(rsErrorMessage, [ rsMissingInputFlag ]));
110+
end;
111+
end;
112+
{$ENDIF}
113+
56114
end.
57115

0 commit comments

Comments
 (0)