index f3331d816e68d994a3bd234972172c3733184554..ea71555c68ff7a6d4c4fa2db980990e96f41d8e0 100644 (file)
--- a/src/shared/hashtable.pas
+++ b/src/shared/hashtable.pas
private
type
+ TEntryArray = array of TEntry;
+
TValEnumerator = record
private
- mEntries: PEntry;
+ mEntries: TEntryArray;
mFirstEntry, mLastEntry, cur: Integer;
public
- constructor Create (aents: PEntry; afirst, alast: Integer);
- function MoveNext: Boolean;
- function getCurrent (): ValueT;
+ constructor Create (const aents: TEntryArray; afirst, alast: Integer);
+ function MoveNext (): Boolean; inline;
+ function getCurrent (): ValueT; inline;
property Current: ValueT read getCurrent;
end;
TKeyEnumerator = record
private
- mEntries: PEntry;
+ mEntries: TEntryArray;
mFirstEntry, mLastEntry, cur: Integer;
public
- constructor Create (aents: PEntry; afirst, alast: Integer);
- function MoveNext: Boolean;
- function getCurrent (): KeyT;
+ constructor Create (const aents: TEntryArray; afirst, alast: Integer);
+ function MoveNext (): Boolean; inline;
+ function getCurrent (): KeyT; inline;
property Current: KeyT read getCurrent;
end;
TKeyValEnumerator = record
private
- mEntries: PEntry;
+ mEntries: TEntryArray;
mFirstEntry, mLastEntry, cur: Integer;
public
- constructor Create (aents: PEntry; afirst, alast: Integer);
- function MoveNext: Boolean;
- function getCurrent (): PEntry;
+ constructor Create (const aents: TEntryArray; afirst, alast: Integer);
+ function MoveNext (): Boolean; inline;
+ function getCurrent (): PEntry; inline;
property Current: PEntry read getCurrent;
end;
equfn: TEquFn;
mBuckets: array of PEntry; // entries, points to mEntries elements
mBucketsUsed: Integer;
- mEntries: array of TEntry;
+ mEntries: TEntryArray;
{$IFDEF RBHASH_SANITY_CHECKS}
mEntriesUsed: Integer;
{$ENDIF}
type
THashIntInt = specialize THashBase<Integer, Integer>;
+ THashStrInt = specialize THashBase<AnsiString, Integer>;
function hashNewIntInt (): THashIntInt;
+function hashNewStrInt (): THashStrInt;
function u32Hash (a: LongWord): LongWord; inline;
function nextPOT (x: LongWord): LongWord; inline;
+// for integer keys
+function hiiequ (constref a, b: Integer): Boolean;
+function hiihash (constref k: Integer): LongWord;
+
+
implementation
uses
// ////////////////////////////////////////////////////////////////////////// //
function hiiequ (constref a, b: Integer): Boolean; begin result := (a = b); end;
+function hsiequ (constref a, b: AnsiString): Boolean; begin result := (a = b); end;
{$PUSH}
{$RANGECHECKS OFF}
function hiihash (constref k: Integer): LongWord;
begin
- result := k;
+ result := LongWord(k);
result -= (result shl 6);
result := result xor (result shr 17);
result -= (result shl 9);
result := result xor (result shl 10);
result := result xor (result shr 15);
end;
+
+function hsihash (constref k: AnsiString): LongWord;
+begin
+ if (Length(k) > 0) then result := fnvHash(PAnsiChar(k)^, Length(k)) else result := 0;
+end;
{$POP}
end;
+function hashNewStrInt (): THashStrInt;
+begin
+ result := THashStrInt.Create(hsihash, hsiequ);
+end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
{$PUSH}
{$RANGECHECKS OFF}
// enumerators
function THashBase.GetEnumerator (): TValEnumerator;
begin
- if (Length(mEntries) > 0) then result := TValEnumerator.Create(@mEntries[0], mFirstEntry, mLastEntry)
+ if (Length(mEntries) > 0) then result := TValEnumerator.Create(mEntries, mFirstEntry, mLastEntry)
else result := TValEnumerator.Create(nil, -1, -1);
end;
function THashBase.byKey (): TKeyEnumerator;
begin
- if (Length(mEntries) > 0) then result := TKeyEnumerator.Create(@mEntries[0], mFirstEntry, mLastEntry)
+ if (Length(mEntries) > 0) then result := TKeyEnumerator.Create(mEntries, mFirstEntry, mLastEntry)
else result := TKeyEnumerator.Create(nil, -1, -1);
end;
function THashBase.byValue (): TValEnumerator;
begin
- if (Length(mEntries) > 0) then result := TValEnumerator.Create(@mEntries[0], mFirstEntry, mLastEntry)
+ if (Length(mEntries) > 0) then result := TValEnumerator.Create(mEntries, mFirstEntry, mLastEntry)
else result := TValEnumerator.Create(nil, -1, -1);
end;
function THashBase.byKeyValue (): TKeyValEnumerator; // PEntry
begin
- if (Length(mEntries) > 0) then result := TKeyValEnumerator.Create(@mEntries[0], mFirstEntry, mLastEntry)
+ if (Length(mEntries) > 0) then result := TKeyValEnumerator.Create(mEntries, mFirstEntry, mLastEntry)
else result := TKeyValEnumerator.Create(nil, -1, -1);
end;
// ////////////////////////////////////////////////////////////////////////// //
-constructor THashBase.TValEnumerator.Create (aents: PEntry; afirst, alast: Integer);
+constructor THashBase.TValEnumerator.Create (const aents: TEntryArray; afirst, alast: Integer);
begin
mEntries := aents;
mFirstEntry := afirst;
cur := mFirstEntry-1;
end;
-function THashBase.TValEnumerator.MoveNext: Boolean;
+function THashBase.TValEnumerator.MoveNext (): Boolean; inline;
begin
Inc(cur);
while (cur <= mLastEntry) do
result := false;
end;
-function THashBase.TValEnumerator.getCurrent (): ValueT;
+function THashBase.TValEnumerator.getCurrent (): ValueT; inline;
begin
result := mEntries[cur].value;
end;
// ////////////////////////////////////////////////////////////////////////// //
-constructor THashBase.TKeyEnumerator.Create (aents: PEntry; afirst, alast: Integer);
+constructor THashBase.TKeyEnumerator.Create (const aents: TEntryArray; afirst, alast: Integer);
begin
mEntries := aents;
mFirstEntry := afirst;
cur := mFirstEntry-1;
end;
-function THashBase.TKeyEnumerator.MoveNext: Boolean;
+function THashBase.TKeyEnumerator.MoveNext (): Boolean; inline;
begin
Inc(cur);
while (cur <= mLastEntry) do
result := false;
end;
-function THashBase.TKeyEnumerator.getCurrent (): KeyT;
+function THashBase.TKeyEnumerator.getCurrent (): KeyT; inline;
begin
result := mEntries[cur].key;
end;
// ////////////////////////////////////////////////////////////////////////// //
-constructor THashBase.TKeyValEnumerator.Create (aents: PEntry; afirst, alast: Integer);
+constructor THashBase.TKeyValEnumerator.Create (const aents: TEntryArray; afirst, alast: Integer);
begin
mEntries := aents;
mFirstEntry := afirst;
cur := mFirstEntry-1;
end;
-function THashBase.TKeyValEnumerator.MoveNext: Boolean;
+function THashBase.TKeyValEnumerator.MoveNext (): Boolean; inline;
begin
Inc(cur);
while (cur <= mLastEntry) do
result := false;
end;
-function THashBase.TKeyValEnumerator.getCurrent (): PEntry;
+function THashBase.TKeyValEnumerator.getCurrent (): PEntry; inline;
begin
- result := mEntries+cur;
+ result := @mEntries[cur];
end;