DEADSOFTWARE

game: `e_GetDir()` -> `e_GetWriteableDir()`, with slight changes in logic
[d2df-sdl.git] / src / shared / hashtable.pas
index 98c924d20bddb1176a3246f10aec6f10ea57cfda..cb6d35c0f8c684b58320c369907b9a3141e1d664 100644 (file)
@@ -2,8 +2,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -205,14 +204,18 @@ type
 type
   THashIntInt = specialize THashBase<Integer, Integer, THashKeyInt>;
   THashStrInt = specialize THashBase<AnsiString, Integer, THashKeyStr>;
+  THashStrCIInt = specialize THashBase<AnsiString, Integer, THashKeyStrAnsiCI>;
   THashIntStr = specialize THashBase<Integer, AnsiString, THashKeyInt>;
   THashStrStr = specialize THashBase<AnsiString, AnsiString, THashKeyStr>;
+  THashStrCIStr = specialize THashBase<AnsiString, AnsiString, THashKeyStrAnsiCI>;
   THashStrVariant = specialize THashBase<AnsiString, Variant, THashKeyStr>;
+  THashStrCIVariant = specialize THashBase<AnsiString, Variant, THashKeyStrAnsiCI>;
 
 
 function u32Hash (a: LongWord): LongWord; inline;
 function fnvHash (constref buf; len: LongWord): LongWord;
 function joaatHash (constref buf; len: LongWord; seed: LongWord=0): LongWord;
+function joaatHashPtr (buf: Pointer; len: LongWord; seed: LongWord=0): LongWord;
 
 // has to be public due to FPC generics limitation
 function nextPOTU32 (x: LongWord): LongWord; inline;
@@ -311,6 +314,26 @@ begin
   result := result xor (result shr 11);
   result += (result shl 15);
 end;
+
+function joaatHashPtr (buf: Pointer; len: LongWord; seed: LongWord=0): LongWord;
+var
+  b: PByte;
+  f: LongWord;
+begin
+  result := seed;
+  b := PByte(buf);
+  for f := 1 to len do
+  begin
+    result += b^;
+    result += (result shl 10);
+    result := result xor (result shr 6);
+    Inc(b);
+  end;
+  // finalize
+  result += (result shl 3);
+  result := result xor (result shr 11);
+  result += (result shl 15);
+end;
 {$POP}
 
 {$PUSH}
@@ -417,7 +440,7 @@ begin
 end;
 {$POP}
 
-class function THashKeyStrAnsiCI.hash (const k: AnsiString): LongWord; inline; begin if (Length(k) > 0) then result := fnvHash((@k[1])^, Length(k)) else result := 0; end;
+class function THashKeyStrAnsiCI.hash (const k: AnsiString): LongWord; inline; begin if (Length(k) > 0) then result := fnvHashLo((@k[1])^, Length(k)) else result := 0; end;
 class function THashKeyStrAnsiCI.equ (const a, b: AnsiString): Boolean; inline;
 var
   f: Integer;
@@ -949,7 +972,7 @@ begin
       lastfree := e;
     end;
   end;
-  if (lastfree <> nil) then e.nextFree := nil;
+  if (lastfree <> nil) then lastfree.nextFree := nil;
   {$IFDEF RBHASH_SANITY_CHECKS}
   if (cnt <> mBucketsUsed) then raise Exception.Create('internal error in hash table resize (invalid first/last range; 0)');
   if (cnt <> mEntriesUsed) then raise Exception.Create('internal error in hash table resize (invalid first/last range; 1)');