Skip to content

Commit 096b85f

Browse files
authored
Merge pull request #145 from georges-hatem/main
remove station names from record
2 parents 4b7a84b + 1d830dc commit 096b85f

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

entries/ghatem-fpc/src/onebrc.pas

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ function RoundExDouble(const ATemp: Double): Double; inline;
2222
Max: SmallInt;
2323
Count: UInt32;
2424
Sum: Integer;
25-
Name: AnsiString;
2625
end;
2726
PStationData = ^TStationData;
2827

2928
TKeys = array [0..45006] of Cardinal;
29+
TStationNames = array [0..45006] of AnsiString;
3030
TValues = array [0..45006] of PStationData;
3131

3232
{ TMyDictionary }
@@ -36,13 +36,16 @@ TMyDictionary = class
3636
FHashes: TKeys;
3737
FValues: TValues;
3838
FRecords: array [0..45006] of TStationData;
39+
// store the station names outside of the record as they are filled only upon first encounter
40+
FStationNames: TStationNames;
3941
procedure InternalFind(const aKey: Cardinal; out aFound: Boolean; out aIndex: Integer);
4042
public
4143
constructor Create;
4244
property Keys: TKeys read FHashes;
45+
property StationNames: TStationNames read FStationNames;
4346
property Values: TValues read FValues;
4447
function TryGetValue (const aKey: Cardinal; out aValue: PStationData): Boolean; inline;
45-
procedure Add (const aKey: Cardinal; const aValue: PStationData); inline;
48+
procedure Add (const aKey: Cardinal; const aValue: PStationData; const aStationName: AnsiString); inline;
4649
end;
4750

4851
{ TOneBRC }
@@ -139,6 +142,7 @@ procedure TMyDictionary.InternalFind(const aKey: Cardinal; out aFound: Boolean;
139142
end
140143
else begin
141144
vOffset := 1;
145+
142146
while True do begin
143147
// quadratic probing, by incrementing vOffset
144148
Inc (vIdx, vOffset);
@@ -181,7 +185,7 @@ function TMyDictionary.TryGetValue(const aKey: Cardinal; out aValue: PStationDat
181185
aValue := FValues[vIdx];
182186
end;
183187

184-
procedure TMyDictionary.Add(const aKey: Cardinal; const aValue: PStationData);
188+
procedure TMyDictionary.Add(const aKey: Cardinal; const aValue: PStationData; const aStationName: AnsiString);
185189
var
186190
vIdx: Integer;
187191
vFound: Boolean;
@@ -190,6 +194,7 @@ procedure TMyDictionary.Add(const aKey: Cardinal; const aValue: PStationData);
190194
if not vFound then begin
191195
FHashes[vIdx] := aKey;
192196
FValues[vIdx] := aValue;
197+
FStationNames[vIdx] := aStationName;
193198
end
194199
else
195200
raise Exception.Create ('TMyDict: cannot add, duplicate key');
@@ -350,8 +355,7 @@ procedure TOneBRC.ProcessData (aThreadNb: UInt16; aStartIdx: Int64; aEndIdx: Int
350355
vData^.Max := vTemp;
351356
vData^.Sum := vTemp;
352357
vData^.Count := 1;
353-
vData^.Name := vStation;
354-
FStationsDicts[aThreadNb].Add (vHash, vData);
358+
FStationsDicts[aThreadNb].Add (vHash, vData, vStation);
355359
end;
356360

357361
// we're at a #10: next line starts at the next index
@@ -376,8 +380,10 @@ procedure TOneBRC.Merge(aLeft: UInt16; aRight: UInt16);
376380
var iHash: Cardinal;
377381
vDataR: PStationData;
378382
vDataL: PStationData;
383+
I: Integer;
379384
begin
380-
for iHash in FStationsDicts[aRight].Keys do begin
385+
for I := 0 to cDictSize - 1 do begin
386+
iHash := FStationsDicts[aRight].Keys[I];
381387
// zero means empty slot: skip
382388
if iHash = 0 then
383389
continue;
@@ -387,13 +393,14 @@ procedure TOneBRC.Merge(aLeft: UInt16; aRight: UInt16);
387393
if FStationsDicts[aLeft].TryGetValue(iHash, vDataL) then begin
388394
vDataL^.Count := vDataL^.Count + vDataR^.Count;
389395
vDataL^.Sum := vDataL^.Sum + vDataR^.Sum;
396+
390397
if vDataR^.Max > vDataL^.Max then
391398
vDataL^.Max := vDataR^.Max;
392399
if vDataR^.Min < vDataL^.Min then
393400
vDataL^.Min := vDataR^.Min;
394401
end
395402
else begin
396-
FStationsDicts[aLeft].Add (iHash, vDataR);
403+
FStationsDicts[aLeft].Add (iHash, vDataR, FStationsDicts[aRight].StationNames[I]);
397404
end;
398405
end;
399406
end;
@@ -419,14 +426,16 @@ procedure TOneBRC.GenerateOutput;
419426
begin
420427
vStream := TStringStream.Create;
421428
vStations := TStringList.Create;
422-
vStations.Capacity := 45000;
429+
vStations.Capacity := cDictSize;
423430
vStations.UseLocale := False;
424431
try
425432
vStations.BeginUpdate;
426-
for vData in FStationsDicts[0].Values do begin
433+
for I := 0 to cDictSize - 1 do begin
434+
vData := FStationsDicts[0].Values[I];
427435
// count = 0 means empty slot: skip
428-
if vData^.Count <> 0 then
429-
vStations.Add(vData^.Name);
436+
if vData^.Count <> 0 then begin
437+
vStations.Add(FStationsDicts[0].StationNames[I]);
438+
end;
430439
end;
431440
vStations.EndUpdate;
432441

0 commit comments

Comments
 (0)