Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hashmaps #57

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 16 additions & 157 deletions src/FLRE.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,6 @@ TFLRECacheHashMap=class
TFLRECache=class
private
ParallelLock:TFLREParallelLock;
List:TList;
HashMap:TFLRECacheHashMap;
public
constructor Create;
Expand All @@ -1282,6 +1281,8 @@ TFLRECache=class
var FLREMaximalRepetitionCount:TFLREInt32=4096;

function FLREPtrCopy(const Src:PFLRERawByteChar;const From,Len:TFLREInt32):TFLRERawByteString;
function FLREHashData(const Data:pointer;Len:TFLREUInt32):TFLREUInt32;
function FLREHashString(const Str: String): TFLREUInt32; {$ifdef caninline}inline;{$endif}

function FLREGetVersion:TFLREUInt32; {$ifdef win32}{$ifdef cpu386}stdcall;{$endif}{$endif}
function FLREGetVersionString:PFLRERawByteChar; {$ifdef win32}{$ifdef cpu386}stdcall;{$endif}{$endif}
Expand Down Expand Up @@ -7843,122 +7844,7 @@ function GetMinimalPerfectHashTableValue(const Seeds,Keys,Values:pointer;const S
end;
end;

function HashString(const Str:TFLRERawByteString):TFLREUInt32;
{$ifdef cpuarm}
var b:PFLRERawByteChar;
len,h,i:TFLREUInt32;
begin
result:=2166136261;
len:=length(Str);
h:=len;
if len>0 then begin
b:=PFLRERawByteChar(Str);
while len>3 do begin
i:=TFLREUInt32(pointer(b)^);
h:=(h xor i) xor $2e63823a;
inc(h,(h shl 15) or (h shr (32-15)));
dec(h,(h shl 9) or (h shr (32-9)));
inc(h,(h shl 4) or (h shr (32-4)));
dec(h,(h shl 1) or (h shr (32-1)));
h:=h xor (h shl 2) or (h shr (32-2));
result:=result xor i;
inc(result,(result shl 1)+(result shl 4)+(result shl 7)+(result shl 8)+(result shl 24));
inc(b,4);
dec(len,4);
end;
if len>1 then begin
i:=TFLREUInt16(pointer(b)^);
h:=(h xor i) xor $2e63823a;
inc(h,(h shl 15) or (h shr (32-15)));
dec(h,(h shl 9) or (h shr (32-9)));
inc(h,(h shl 4) or (h shr (32-4)));
dec(h,(h shl 1) or (h shr (32-1)));
h:=h xor (h shl 2) or (h shr (32-2));
result:=result xor i;
inc(result,(result shl 1)+(result shl 4)+(result shl 7)+(result shl 8)+(result shl 24));
inc(b,2);
dec(len,2);
end;
if len>0 then begin
i:=TFLREUInt8(b^);
h:=(h xor i) xor $2e63823a;
inc(h,(h shl 15) or (h shr (32-15)));
dec(h,(h shl 9) or (h shr (32-9)));
inc(h,(h shl 4) or (h shr (32-4)));
dec(h,(h shl 1) or (h shr (32-1)));
h:=h xor (h shl 2) or (h shr (32-2));
result:=result xor i;
inc(result,(result shl 1)+(result shl 4)+(result shl 7)+(result shl 8)+(result shl 24));
end;
end;
result:=result xor h;
if result=0 then begin
result:=$ffffffff;
end;
end;
{$else}
const m=TFLREUInt32($57559429);
n=TFLREUInt32($5052acdb);
var b:PFLRERawByteChar;
h,k,len:TFLREUInt32;
p:{$ifdef fpc}TFLREUInt64{$else}TFLREInt64{$endif};
begin
len:=length(Str);
h:=len;
k:=h+n+1;
if len>0 then begin
b:=PFLRERawByteChar(Str);
while len>7 do begin
begin
p:=TFLREUInt32(pointer(b)^)*{$ifdef fpc}TFLREUInt64{$else}TFLREInt64{$endif}(n);
h:=h xor TFLREUInt32(p and $ffffffff);
k:=k xor TFLREUInt32(p shr 32);
inc(b,4);
end;
begin
p:=TFLREUInt32(pointer(b)^)*{$ifdef fpc}TFLREUInt64{$else}TFLREInt64{$endif}(m);
k:=k xor TFLREUInt32(p and $ffffffff);
h:=h xor TFLREUInt32(p shr 32);
inc(b,4);
end;
dec(len,8);
end;
if len>3 then begin
p:=TFLREUInt32(pointer(b)^)*{$ifdef fpc}TFLREUInt64{$else}TFLREInt64{$endif}(n);
h:=h xor TFLREUInt32(p and $ffffffff);
k:=k xor TFLREUInt32(p shr 32);
inc(b,4);
dec(len,4);
end;
if len>0 then begin
if len>1 then begin
p:=TFLREUInt16(pointer(b)^);
inc(b,2);
dec(len,2);
end else begin
p:=0;
end;
if len>0 then begin
p:=p or (TFLREUInt8(b^) shl 16);
end;
p:=p*{$ifdef fpc}TFLREUInt64{$else}TFLREInt64{$endif}(m);
k:=k xor TFLREUInt32(p and $ffffffff);
h:=h xor TFLREUInt32(p shr 32);
end;
end;
begin
p:=(h xor (k+n))*{$ifdef fpc}TFLREUInt64{$else}TFLREInt64{$endif}(n);
h:=h xor TFLREUInt32(p and $ffffffff);
k:=k xor TFLREUInt32(p shr 32);
end;
result:=k xor h;
if result=0 then begin
result:=$ffffffff;
end;
end;
{$endif}

function HashData(const Data:pointer;Len:TFLREUInt32):TFLREUInt32;
function FLREHashData(const Data:pointer;Len:TFLREUInt32):TFLREUInt32;
{$ifdef cpuarm}
var b:PFLRERawByteChar;
h,i:TFLREUInt32;
Expand Down Expand Up @@ -8071,6 +7957,11 @@ function HashData(const Data:pointer;Len:TFLREUInt32):TFLREUInt32;
end;
{$endif}

function FLREHashString(const Str: String): TFLREUInt32; {$ifdef caninline}inline;{$endif}
begin
result := FLREHashData(pchar(Str), length(Str));
end;

function UTF8RangeToRegEx(Lo,Hi:TFLREUInt32):TFLRERawByteString;
type TString6Chars=array[0..6] of TFLRERawByteChar;
const Seq0010ffff:array[0..6,0..4,0..1] of TFLREInt32=((($00,$7f),(-1,-1),(-1,-1),(-1,-1),(-1,-1)), // 00-7F
Expand Down Expand Up @@ -8224,7 +8115,7 @@ function UTF8RangeToRegEx(Lo,Hi:TFLREUInt32):TFLRERawByteString;
function HashDFAState(const Key:PFLREDFAState):TFLREUInt32;
begin
if assigned(Key) and (Key.CountInstructions>0) then begin
result:=HashData(@Key.Instructions[0],Key.CountInstructions*sizeof(PFLREInstruction));
result:=FLREHashData(@Key.Instructions[0],Key.CountInstructions*sizeof(PFLREInstruction));
result:=result xor ((TFLREUInt32(Key.CountInstructions) shr 16) or (TFLREUInt32(Key.CountInstructions) shl 16));
result:=result xor (((Key.Flags and sfDFACacheMask) shl 19) or ((Key.Flags and sfDFACacheMask) shr 13));
if result=0 then begin
Expand Down Expand Up @@ -8501,7 +8392,6 @@ constructor TFLREDFAStateHashMap.Create;
destructor TFLREDFAStateHashMap.Destroy;
begin
Clear;
SetLength(Entities,0);
inherited Destroy;
end;

Expand Down Expand Up @@ -9197,24 +9087,14 @@ constructor TFLREStringIntegerPairHashMap.Create;
end;

destructor TFLREStringIntegerPairHashMap.Destroy;
var Counter:TFLREInt32;
begin
Clear;
for Counter:=0 to length(Entities)-1 do begin
Entities[Counter].Key:='';
end;
SetLength(Entities,0);
SetLength(EntityToCellIndex,0);
SetLength(CellToEntityIndex,0);
inherited Destroy;
end;

procedure TFLREStringIntegerPairHashMap.Clear;
var Counter:TFLREInt32;
begin
for Counter:=0 to length(Entities)-1 do begin
Entities[Counter].Key:='';
end;
RealSize:=0;
LogSize:=0;
Size:=0;
Expand All @@ -9239,7 +9119,7 @@ function TFLREStringIntegerPairHashMap.FindCell(const Key:TFLRERawByteString):TF
var HashCode,Mask,Step:TFLREUInt32;
Entity:TFLREInt32;
begin
HashCode:=HashString(Key);
HashCode:=FLREHashString(Key);
Mask:=(2 shl LogSize)-1;
Step:=((HashCode shl 1)+1) and Mask;
if LogSize<>0 then begin
Expand Down Expand Up @@ -9397,9 +9277,6 @@ constructor TFLRECharClassHashMap.Create;
destructor TFLRECharClassHashMap.Destroy;
begin
Clear;
SetLength(Entities,0);
SetLength(EntityToCellIndex,0);
SetLength(CellToEntityIndex,0);
inherited Destroy;
end;

Expand All @@ -9418,7 +9295,7 @@ function TFLRECharClassHashMap.FindCell(const Key:TFLRECharClass):TFLREUInt32;
var HashCode,Mask,Step:TFLREUInt32;
Entity:TFLREInt32;
begin
HashCode:=HashData(@Key,SizeOf(TFLRECharClass));
HashCode:=FLREHashData(@Key,SizeOf(TFLRECharClass));
Mask:=(2 shl LogSize)-1;
Step:=((HashCode shl 1)+1) and Mask;
if LogSize<>0 then begin
Expand Down Expand Up @@ -21790,24 +21667,13 @@ constructor TFLRECacheHashMap.Create;
end;

destructor TFLRECacheHashMap.Destroy;
var Counter:TFLREInt32;
begin
Clear;
for Counter:=0 to length(Entities)-1 do begin
Entities[Counter].Key:='';
end;
SetLength(Entities,0);
SetLength(EntityToCellIndex,0);
SetLength(CellToEntityIndex,0);
inherited Destroy;
end;

procedure TFLRECacheHashMap.Clear;
var Counter:TFLREInt32;
begin
for Counter:=0 to length(Entities)-1 do begin
Entities[Counter].Key:='';
end;
RealSize:=0;
LogSize:=0;
Size:=0;
Expand All @@ -21821,7 +21687,7 @@ function TFLRECacheHashMap.FindCell(const Key:TFLRERawByteString):TFLREUInt32;
var HashCode,Mask,Step:TFLREUInt32;
Entity:TFLREInt32;
begin
HashCode:=HashString(Key);
HashCode:=FLREHashString(Key);
Mask:=(2 shl LogSize)-1;
Step:=((HashCode shl 1)+1) and Mask;
if LogSize<>0 then begin
Expand Down Expand Up @@ -21968,17 +21834,14 @@ constructor TFLRECache.Create;
begin
inherited Create;
ParallelLock:=0;
List:=TList.Create;
HashMap:=TFLRECacheHashMap.Create;
end;

destructor TFLRECache.Destroy;
var Index:TFLREInt32;
begin
for Index:=0 to List.Count-1 do begin
TFLRE(List[Index]).Free;
end;
List.Free;
for Index:=0 to HashMap.Size - 1 do
HashMap.Entities[Index].Value.Free;
HashMap.Free;
inherited Destroy;
end;
Expand All @@ -21988,10 +21851,8 @@ procedure TFLRECache.Clear;
begin
ParallelLockEnter(@ParallelLock);
try
for Index:=0 to List.Count-1 do begin
TFLRE(List[Index]).Free;
end;
List.Clear;
for Index:=0 to HashMap.Size - 1 do
HashMap.Entities[Index].Value.Free;
HashMap.Clear;
finally
ParallelLockLeave(@ParallelLock);
Expand All @@ -22007,7 +21868,6 @@ function TFLRECache.Get(const ARegularExpression:TFLRERawByteString;const AFlags
result:=HashMap.GetValue(HashKey);
if not assigned(result) then begin
result:=TFLRE.Create(ARegularExpression,AFlags);
List.Add(result);
HashMap.Add(HashKey,result);
end;
finally
Expand All @@ -22028,7 +21888,6 @@ function TFLRECache.Get(const ARegularExpressions:array of TFLRERawByteString;co
result:=HashMap.GetValue(HashKey);
if not assigned(result) then begin
result:=TFLRE.Create(ARegularExpressions,AFlags);
List.Add(result);
HashMap.Add(HashKey,result);
end;
finally
Expand Down