11unit Generate.Common;
22
3+ { $IFDEF FPC}
34{ $mode ObjFPC}{ $H+}
5+ { $ENDIF}
46
57interface
68
79uses
8- Classes
9- , SysUtils
10- , streamex
11- ;
10+ Classes, SysUtils, Math
11+ { $IFDEF FPC}
12+ , streamex, bufstream
13+ { $ELSE}
14+ , System.Diagnostics
15+ { $ENDIF}
16+ ;
1217
1318const
1419 cSeed: LongInt = 46668267 ; // '1BRC' in ASCII
1520 cColdestTemp = -99.9 ;
1621 cHottestTemp = 99.9 ;
22+ cLineBreak = #13 #10 ;
1723
1824type
19- { TGenerator }
25+ { TGenerator }
2026 TGenerator = class (TObject)
2127 private
2228 FInputFile: String;
@@ -25,10 +31,8 @@ TGenerator = class(TObject)
2531 FStationNames: TStringList;
2632
2733 procedure BuildStationNames ;
28- function GenerateProgressBar (
29- APBPosition, APBMax, APBWIdth, AFileSize:Int64;
30- ATimeElapsed: TDateTime
31- ):String;
34+ function GenerateProgressBar (APBPosition, APBMax, APBWIdth, AFileSize: Int64;
35+ ATimeElapsed: TDateTime): String;
3236 protected
3337 public
3438 constructor Create(AInputFile, AOutputFile: String; ALineCount: Int64);
@@ -38,34 +42,31 @@ TGenerator = class(TObject)
3842 published
3943 end ;
4044
41- implementation
45+ { $IFNDEF FPC }
4246
43- uses
44- Math,
45- bufstream
46- ;
47+ TStringArray = array of string;
48+ TWriteBufStream = TFileStream;
49+ { $ENDIF}
50+
51+ implementation
4752
4853const
4954 batchPercent = 10 ;
5055
51- { TGenerator }
56+ { TGenerator }
5257
53- constructor TGenerator.Create(
54- AInputFile,
55- AOutputFile: String;
56- ALineCount: Int64
57- );
58+ constructor TGenerator.Create(AInputFile, AOutputFile: String; ALineCount: Int64);
5859begin
59- FInputFile:= AInputFile;
60- FOutPutFile:= AOutputFile;
61- FLineCount:= ALineCount;
62-
63- FStationNames:= TStringList.Create;
64- FStationNames.Capacity:= 50000 ;
65- // FStationNames.CaseSensitive:= False;
66- FStationNames.UseLocale:= False;
67- FStationNames.Duplicates:= dupIgnore;
68- FStationNames.Sorted:= True;
60+ FInputFile := AInputFile;
61+ FOutPutFile := AOutputFile;
62+ FLineCount := ALineCount;
63+
64+ FStationNames := TStringList.Create;
65+ FStationNames.Capacity := 50000 ;
66+ // FStationNames.CaseSensitive:= False;
67+ FStationNames.UseLocale := False;
68+ FStationNames.Duplicates := dupIgnore;
69+ FStationNames.Sorted := True;
6970end ;
7071
7172destructor TGenerator.Destroy;
@@ -79,30 +80,46 @@ procedure TGenerator.BuildStationNames;
7980 inputStream: TFileStream;
8081 streamReader: TStreamReader;
8182 entry: String;
82- count: Int64 = 0 ;
83- start, stop: QWord;
83+ count: Int64;
84+ start, stop: { $IFDEF FPC } QWord{ $ELSE } Int64 { $ENDIF } ;
8485begin
8586 WriteLn(' Building Weather Stations...' );
8687 // Load the Weather Station names
8788 if FileExists(FInputFile) then
8889 begin
89- inputStream:= TFileStream.Create(FInputFile, fmOpenRead);
90+ inputStream := TFileStream.Create(FInputFile, fmOpenRead);
9091 try
91- streamReader:= TStreamReader.Create(inputStream);
92+ streamReader := TStreamReader.Create(inputStream);
9293 try
93- start:= GetTickCount64;
94+ { $IFDEF FPC}
95+ start := GetTickCount64;
9496 while not streamReader.Eof do
9597 begin
96- entry:= streamReader.ReadLine;
98+ entry := streamReader.ReadLine;
9799 if entry[1 ] <> ' #' then
98100 begin
99- entry:= entry.Split(' ;' )[0 ];
101+ entry := entry.Split(' ;' )[0 ];
100102 FStationNames.Add(entry);
101- // WriteLn('Got: ', entry);
103+ // WriteLn('Got: ', entry);
102104 Inc(count);
103105 end ;
104106 end ;
105- stop:= GetTickCount64;
107+ stop := GetTickCount64;
108+ { $ELSE}
109+ start := TStopwatch.GetTimeStamp;
110+ while not streamReader.EndOfStream do
111+ begin
112+ entry := streamReader.ReadLine;
113+ if entry[1 ] <> ' #' then
114+ begin
115+ entry := entry.Split([' ;' ])[0 ];
116+ FStationNames.Add(entry);
117+ // WriteLn('Got: ', entry);
118+ Inc(count);
119+ end ;
120+ end ;
121+ stop := TStopwatch.GetTimeStamp;
122+ { $ENDIF}
106123 finally
107124 streamReader.Free;
108125 end ;
@@ -112,35 +129,29 @@ procedure TGenerator.BuildStationNames;
112129 end
113130 else
114131 begin
115- raise Exception.Create(Format(' File "%s" not found.' , [ FInputFile ]));
132+ raise Exception.Create(Format(' File "%s" not found.' , [FInputFile]));
116133 end ;
117- WriteLn(Format(' Done: Processed %.n entries from a total of %.n weather stations in %d ms' , [
118- Double(count),
119- Double(FStationNames.Count),
120- stop-start
121- ]));
134+ WriteLn(Format
135+ (' Done: Processed %.n entries from a total of %.n weather stations in %d ms' ,
136+ [Double(count), Double(FStationNames.count), stop - start]));
122137 WriteLn;
123138end ;
124139
125- function TGenerator.GenerateProgressBar (
126- APBPosition, APBMax, APBWIdth, AFileSize: Int64;
127- ATimeElapsed: TDateTime
128- ): String;
140+ function TGenerator.GenerateProgressBar (APBPosition, APBMax, APBWIdth, AFileSize: Int64;
141+ ATimeElapsed: TDateTime): String;
129142var
130143 percentDone: Double;
131144 filled: Integer;
132145begin
133- percentDone:= (100 * APBPosition) / APBMax;
134- filled:= (APBWIdth * APBPosition ) div APBMax;
135- Result:= ' [' ;
136- Result:= Result + StringOfChar(' #' , filled);
137- Result:= Result + StringOfChar(' -' , APBWIdth - filled);
138- Result:= Result + Format(' ] %5.2f %%' , [ percentDone ]);
139- Result:= Result + Format(' lines: %.n, file size: %.n, elapsed: %s ' , [
140- Double(APBPosition),
141- Double(AFileSize),
142- FormatDateTime(' n" min, "s" sec"' , ATimeElapsed)
143- ]);
146+ percentDone := (100 * APBPosition) / APBMax;
147+ filled := (APBWIdth * APBPosition) div APBMax;
148+ Result := ' [' ;
149+ Result := Result + StringOfChar(' #' , filled);
150+ Result := Result + StringOfChar(' -' , APBWIdth - filled);
151+ Result := Result + Format(' ] %5.2f %%' , [percentDone]);
152+ Result := Result + Format(' lines: %.n, file size: %.n, elapsed: %s ' ,
153+ [Double(APBPosition), Double(AFileSize), FormatDateTime(' n" min, "s" sec"' ,
154+ ATimeElapsed)]);
144155end ;
145156
146157procedure TGenerator.Generate ;
@@ -158,18 +169,18 @@ procedure TGenerator.Generate;
158169begin
159170 // Randomize sets this variable depending on the current time
160171 // We just set it to our own value
161- RandSeed:= cSeed;
172+ RandSeed := cSeed;
162173
163174 // Build list of station names
164175 BuildStationNames;
165176
166- outputFileStream:= TFileStream.Create(FOutPutFile, fmCreate);
177+ outputFileStream := TFileStream.Create(FOutPutFile, fmCreate);
167178
168- progressBatch:= floor(FLineCount * (batchPercent / 100 ));
169- start:= Now;
179+ progressBatch := floor(FLineCount * (batchPercent / 100 ));
180+ start := Now;
170181
171- // based on code @domasz from lazarus forum, github: PascalVault
172- stationsCount := FStationNames.Count ;
182+ // based on code @domasz from lazarus forum, github: PascalVault
183+ stationsCount := FStationNames.count ;
173184 SetLength(stationArray, stationsCount);
174185 for i := 0 to stationsCount - 1 do
175186 stationArray[i] := FStationNames[i];
@@ -181,10 +192,15 @@ procedure TGenerator.Generate;
181192 begin
182193 randomTempStr := IntToStr(i);
183194 case Ord(randomTempStr[0 ]) of
184- 1 : randomTempFinal := ' 0.' + randomTempStr;
185- 2 : randomTempFinal := randomTempStr[1 ] + ' .' + randomTempStr[2 ];
186- 3 : randomTempFinal := randomTempStr[1 ] + randomTempStr[2 ] + ' .' + randomTempStr[3 ];
187- 4 : randomTempFinal := randomTempStr[1 ] + randomTempStr[2 ] + randomTempStr[3 ] + ' .' + randomTempStr[4 ];
195+ 1 :
196+ randomTempFinal := ' 0.' + randomTempStr;
197+ 2 :
198+ randomTempFinal := randomTempStr[1 ] + ' .' + randomTempStr[2 ];
199+ 3 :
200+ randomTempFinal := randomTempStr[1 ] + randomTempStr[2 ] + ' .' + randomTempStr[3 ];
201+ 4 :
202+ randomTempFinal := randomTempStr[1 ] + randomTempStr[2 ] + randomTempStr[3 ] + ' .' +
203+ randomTempStr[4 ];
188204 end ;
189205 temperatureArray[i * 2 - 1 ] := randomTempFinal;
190206 temperatureArray[i * 2 ] := ' -' + randomTempFinal;
@@ -194,55 +210,60 @@ procedure TGenerator.Generate;
194210 line := ' ' ;
195211
196212 try
197- // outputBufWriter:= TWriteBufStream.Create(outputFileStream, 4*1024);
198- outputBufWriter:= TWriteBufStream.Create(outputFileStream, 64 *1024 );
213+ // outputBufWriter:= TWriteBufStream.Create(outputFileStream, 4*1024);
214+ { $IFDEF FPC}
215+ outputBufWriter := TWriteBufStream.Create(outputFileStream, 64 * 1024 );
216+ { $ENDIF}
199217 try
200- Write(GenerateProgressBar(1 , FLineCount, 50 , 0 , Now - start), # 13 );
218+ Write(GenerateProgressBar(1 , FLineCount, 50 , 0 , Now - start), cLineBreak );
201219 // Generate the file
202- for index:= 1 to FLineCount do
220+ for index := 1 to FLineCount do
203221 begin
204- stationId:= Random(stationsCount);
222+ stationId := Random(stationsCount);
205223 // This is all paweld magic:
206224 // From here
207- randomTemp:= Random(temperaturesCount);
208- line := line + stationArray[stationId] + ' ;' + temperatureArray[randomTemp] + #13 #10 ;
209- // Write(line);
225+ randomTemp := Random(temperaturesCount);
226+ line := line + stationArray[stationId] + ' ;' + temperatureArray[randomTemp] +
227+ cLineBreak;
228+ // Write(line);
210229 if index mod 10000 = 0 then
211230 begin
231+ { $IFNDEF FPC}
232+ outputFileStream.WriteBuffer(line[1 ], Length(line));
233+ { $ELSE}
212234 outputBufWriter.WriteBuffer(line[1 ], Length(line));
235+ { $ENDIF}
213236 line := ' ' ;
214237 end ;
215238 // To here
216239 Dec(progressBatch);
217240 if progressBatch = 0 then
218241 begin
219- Write(GenerateProgressBar(
220- index,
221- FLineCount,
222- 50 ,
223- outputFileStream.Size,
224- Now - start
225- ), #13 );
226- progressBatch:= floor(FLineCount * (batchPercent / 100 ));
242+ Write(GenerateProgressBar(index, FLineCount, 50 , outputFileStream.Size,
243+ Now - start), cLineBreak);
244+ progressBatch := floor(FLineCount * (batchPercent / 100 ));
227245 end ;
228246 end ;
229247 if line <> ' ' then
230248 begin
249+ { $IFNDEF FPC}
250+ outputFileStream.WriteBuffer(line[1 ], Length(line));
251+ { $ELSE}
231252 outputBufWriter.WriteBuffer(line[1 ], Length(line));
253+ { $ENDIF}
232254 end ;
233255 finally
256+ { $IFDEF FPC}
234257 outputBufWriter.Free;
258+ { $ENDIF}
235259 end ;
236260 finally
237261 WriteLn;
238262 WriteLn;
239- WriteLn(Format(' Done: file size: %.n, elapsed: %s' , [
240- Double(outputFileStream.Size),
241- FormatDateTime(' n" min, "s" sec"' , Now - start)
242- ]));
263+ WriteLn(Format(' Done: file size: %.n, elapsed: %s' , [Double(outputFileStream.Size),
264+ FormatDateTime(' n" min, "s" sec"' , Now - start)]));
243265 outputFileStream.Free;
244266 end ;
245267end ;
246268
247269end .
248-
0 commit comments