77interface
88
99uses
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
2218type
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
5748const
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);
7162begin
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;
8172end ;
8273
8374destructor 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;
9687begin
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;
143139end ;
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;
149143var
150144 percentDone: Double;
151145 filled: Integer;
152146begin
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)]);
164156end ;
165157
166158procedure TGenerator.Generate ;
@@ -178,20 +170,20 @@ procedure TGenerator.Generate;
178170begin
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 ;
278275end ;
279276
280277end .
281-
0 commit comments