X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fshared%2Fhashtable.pas;h=8aaa522a45bae64530243a8fa031f42b4b035b4f;hb=3d8489bb2d74d08d3a9ccad06eea7e8fb7d4038d;hp=f3331d816e68d994a3bd234972172c3733184554;hpb=053a1b71fc1667d29e9c518be03866aa546078a4;p=d2df-sdl.git diff --git a/src/shared/hashtable.pas b/src/shared/hashtable.pas index f3331d8..8aaa522 100644 --- a/src/shared/hashtable.pas +++ b/src/shared/hashtable.pas @@ -52,36 +52,38 @@ type 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; @@ -90,7 +92,7 @@ type 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} @@ -158,8 +160,12 @@ type type THashIntInt = specialize THashBase; + THashStrInt = specialize THashBase; + THashStrStr = specialize THashBase; function hashNewIntInt (): THashIntInt; +function hashNewStrInt (): THashStrInt; +function hashNewStrStr (): THashStrStr; function u32Hash (a: LongWord): LongWord; inline; @@ -169,6 +175,13 @@ function joaatHash (constref buf; len: LongWord): LongWord; function nextPOT (x: LongWord): LongWord; inline; +// for integer keys +function hiiequ (constref a, b: Integer): Boolean; +function hiihash (constref k: Integer): LongWord; +function hsiequ (constref a, b: AnsiString): Boolean; +function hsihash (constref k: AnsiString): LongWord; + + implementation uses @@ -194,12 +207,13 @@ end; // ////////////////////////////////////////////////////////////////////////// // 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); @@ -208,6 +222,11 @@ begin 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} @@ -217,6 +236,18 @@ begin end; +function hashNewStrInt (): THashStrInt; +begin + result := THashStrInt.Create(hsihash, hsiequ); +end; + + +function hashNewStrStr (): THashStrStr; +begin + result := THashStrStr.Create(hsihash, hsiequ); +end; + + // ////////////////////////////////////////////////////////////////////////// // {$PUSH} {$RANGECHECKS OFF} @@ -905,31 +936,31 @@ end; // 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; @@ -937,7 +968,7 @@ begin cur := mFirstEntry-1; end; -function THashBase.TValEnumerator.MoveNext: Boolean; +function THashBase.TValEnumerator.MoveNext (): Boolean; inline; begin Inc(cur); while (cur <= mLastEntry) do @@ -947,14 +978,14 @@ begin 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; @@ -962,7 +993,7 @@ begin cur := mFirstEntry-1; end; -function THashBase.TKeyEnumerator.MoveNext: Boolean; +function THashBase.TKeyEnumerator.MoveNext (): Boolean; inline; begin Inc(cur); while (cur <= mLastEntry) do @@ -972,14 +1003,14 @@ begin 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; @@ -987,7 +1018,7 @@ begin cur := mFirstEntry-1; end; -function THashBase.TKeyValEnumerator.MoveNext: Boolean; +function THashBase.TKeyValEnumerator.MoveNext (): Boolean; inline; begin Inc(cur); while (cur <= mLastEntry) do @@ -997,9 +1028,9 @@ begin result := false; end; -function THashBase.TKeyValEnumerator.getCurrent (): PEntry; +function THashBase.TKeyValEnumerator.getCurrent (): PEntry; inline; begin - result := mEntries+cur; + result := @mEntries[cur]; end;