Skip to content

Commit 1d431e0

Browse files
committed
ghatem, single-threaded attempt
1 parent 9545df5 commit 1d431e0

7 files changed

Lines changed: 42633 additions & 0 deletions

File tree

entries/ghatem/src/FileReader.pas

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
unit FileReader;
2+
3+
interface
4+
5+
uses
6+
System.Classes, System.SysUtils, System.Types,
7+
Winapi.Windows;
8+
9+
type
10+
TInputReader = class
11+
class procedure MMF(const AFilename: string; var aOut: TArray<AnsiChar>);
12+
end;
13+
14+
implementation
15+
16+
17+
class procedure TInputReader.MMF (const AFilename: string; var aOut: TArray<AnsiChar>);
18+
// procedure found online while searching for memory-mappped files
19+
20+
// PROBLEM-1: GetFileSize was returning ~3.9B, which is incorrect.
21+
// GetFileSizeEx was correctly returning 16B instead.
22+
// PROBLEM-2: CreateFileMapping only accepts Cardinals, which are not enough to fit 16B,
23+
// thus RangeCheck error.
24+
// One way would be to call CreateFileMapping in chunks of acceptable size,
25+
// but a chunk of 3.9B was taking ~1.7 seconds to load.
26+
// so 4 times that was pretty slow, especially that it is a single-threaded operation
27+
var
28+
hFile: THandle;
29+
hFileMap: THandle;
30+
hiSize: Int64;
31+
loSize: Int64;
32+
view: pointer;
33+
begin
34+
if AFilename = '' then
35+
Exit;
36+
if not FileExists(AFilename) then
37+
Exit;
38+
{Open the file}
39+
hFile := CreateFile(
40+
PChar(AFilename), GENERIC_READ, FILE_SHARE_READ, nil,
41+
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
42+
);
43+
if hFile <> INVALID_HANDLE_VALUE then
44+
begin
45+
loSize := GetFileSize(hFile, @hiSize);
46+
{File was opened successfully, now map it:}
47+
hFileMap := CreateFileMapping(
48+
hFile, nil, PAGE_READONLY, hiSize, loSize, 'TextForString'
49+
);
50+
if (hFileMap <> 0) then
51+
begin
52+
if (GetLastError() = ERROR_ALREADY_EXISTS) then
53+
begin
54+
Writeln('Mapping already exists - not created.');
55+
CloseHandle(hFileMap)
56+
end
57+
else
58+
begin
59+
view := nil;
60+
try
61+
{File mapped successfully, now map a view of the file into the
62+
address space:}
63+
view := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
64+
if (view <> nil) then
65+
begin {View mapped successfully}
66+
{Close file handle - as long is view is open it will persist}
67+
CloseHandle(hFile);
68+
SetLength(aOut, loSize);
69+
Move(view^, aOut[0], loSize);
70+
end
71+
else
72+
WriteLn('Unable to map view of file.');
73+
finally
74+
UnmapViewOfFile(view); {Close view}
75+
CloseHandle(hFileMap); {Close mapping}
76+
end
77+
end
78+
end
79+
else
80+
begin
81+
WriteLn('Unable to create file mapping.');
82+
end;
83+
end
84+
else
85+
begin
86+
WriteLn('Unable to open file.');
87+
end;
88+
end;
89+
90+
end.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
program GHatemOneBRC;
2+
3+
{$APPTYPE CONSOLE}
4+
5+
{$R *.res}
6+
7+
{$IFDEF RELEASE}
8+
{$INLINE ON}
9+
{$OPTIMIZATION ON}
10+
{$ASSERTIONS OFF}
11+
{$OVERFLOWCHECKS OFF}
12+
{$RANGECHECKS OFF}
13+
{$ENDIF}
14+
15+
uses
16+
OneBRC in 'OneBRC.pas',
17+
Utils in 'Utils.pas',
18+
console in 'console.pas';
19+
20+
//const
21+
// cInput: string = 'C:\DelphiLabs\1BRC2\data\measurements_1m.txt';
22+
// cInput: string = 'C:\DelphiLabs\1BRC2\data\measurements_100m.txt';
23+
// cInput: string = 'C:\DelphiLabs\1BRC2\data\measurements_1b.txt';
24+
25+
var
26+
vOneBRC: TOneBRC;
27+
vFileName: string;
28+
begin
29+
if ParseCmdLineParams (vFileName) then begin
30+
31+
vOneBRC := TOneBRC.Create;
32+
try
33+
vOneBRC.mORMotMMF (vFileName);
34+
vOneBRC.SingleThread;
35+
vOneBRC.GenerateOutput;
36+
finally
37+
vOneBRC.Free;
38+
end;
39+
40+
{$REGION 'debug'}
41+
// Timer ('read mmfile',
42+
// procedure
43+
// begin
44+
//
45+
// end
46+
// );
47+
//
48+
// for I := 0 to 4 do begin
49+
// Timer ('process single thread',
50+
// procedure
51+
// begin
52+
//
53+
// end
54+
// );
55+
//
56+
// Timer ('generate output',
57+
// procedure
58+
// begin
59+
//
60+
// end
61+
// );
62+
// end;
63+
//
64+
// WriteLn ('DONE!');
65+
// Readln;
66+
{$ENDREGION}
67+
68+
end;
69+
end.

0 commit comments

Comments
 (0)