123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- #pragma once
- #include <AK/SoundEngine/Common/AkHashTableTypes.h>
- namespace AK
- {
- namespace HashTable
- {
- namespace Internal
- {
- template<typename KeyType>
- inline AkInt32 IdealPos(KeyType uKey, AkInt32 iEntriesMask)
- {
- return AkInt32(uKey) & iEntriesMask;
- }
-
- template<typename KeyType>
- AkInt32 DistanceFromIdealPos(AkInt32 iSlot, KeyType uKey, AkInt32 iEntriesMask)
- {
-
-
-
- return (iSlot - AkInt32(uKey)) & iEntriesMask;
- }
-
- template<typename KeyType>
- inline AkInt32 LinearProbe(const KeyType* pKeys, const bool* pbSlotOccupied, KeyType uKey, AkInt32 iSlot, AkUInt32 uNumEntries)
- {
- AkInt32 iDistFromBestSlot = 0;
- AkInt32 iEntriesMask = (AkInt32)uNumEntries - 1;
- for (; ; )
- {
- if (!pbSlotOccupied[iSlot])
- return -1;
- KeyType keyInSlot = pKeys[iSlot];
- if (keyInSlot == uKey)
- break;
- if (iDistFromBestSlot > DistanceFromIdealPos(iSlot, keyInSlot, iEntriesMask))
- return -1;
- iSlot = (iSlot + 1) & iEntriesMask;
- ++iDistFromBestSlot;
- }
- return iSlot;
- }
-
- inline AkInt32 OccupiedProbe(const bool* pbSlotOccupied, AkInt32 iSlot, AkInt32 iNumEntries)
- {
- while (iSlot < iNumEntries)
- {
-
-
- if (AkUInt64 slotOccCompressed = *((AkUInt64*)(pbSlotOccupied + iSlot)))
- {
- iSlot = iSlot + AKPLATFORM::AkBitScanForward64(slotOccCompressed) / 8;
- iSlot = (iSlot >= iNumEntries) ? -1 : iSlot;
- return iSlot;
- }
- else
- {
- iSlot += 8;
- }
- }
- return -1;
- }
- }
-
-
-
- template<typename KeyType>
- inline AkInt32 GetFirstSlotForKey(const AkHashTableBase<KeyType>* pHashTable, KeyType uKey)
- {
- if (pHashTable->uNumReservedEntries == 0)
- return -1;
- AkUInt32 uNumEntries = pHashTable->uNumReservedEntries;
- AkInt32 iBestSlot = uKey & (uNumEntries - 1);
- return Internal::LinearProbe(pHashTable->pKeys, pHashTable->pbSlotOccupied, uKey, iBestSlot, uNumEntries);
- }
-
-
-
- template<typename KeyType>
- inline AkInt32 GetNextSlotForKey(const AkHashTableBase<KeyType>* pHashTable, KeyType uKey, AkInt32 iPreviousSlot)
- {
- if (pHashTable->uNumReservedEntries == 0)
- return -1;
- AkUInt32 uNumEntries = pHashTable->uNumReservedEntries;
- AkInt32 iNextSlot = (iPreviousSlot + 1) & (uNumEntries - 1);
- return Internal::LinearProbe(pHashTable->pKeys, pHashTable->pbSlotOccupied, uKey, iNextSlot, uNumEntries);
- }
-
-
-
- template<typename KeyType>
- inline AkInt32 GetFirstActiveSlot(const AkHashTableBase<KeyType>* pHashTable)
- {
- return Internal::OccupiedProbe(pHashTable->pbSlotOccupied, 0, (AkInt32)pHashTable->uNumReservedEntries);
- }
-
-
-
- template<typename KeyType>
- inline AkInt32 GetNextActiveSlot(const AkHashTableBase<KeyType>* pHashTable, AkInt32 iPreviousSlot)
- {
- return Internal::OccupiedProbe(pHashTable->pbSlotOccupied, iPreviousSlot + 1, (AkInt32)pHashTable->uNumReservedEntries);
- }
-
-
- template<typename KeyType, typename FuncType>
- inline void ForEachSlot(const AkHashTableBase<KeyType>* in_pHashTable, FuncType in_func)
- {
- AkUInt32 uNumReservedEntries = in_pHashTable->uNumReservedEntries;
- bool* pbSlotOccupied = in_pHashTable->pbSlotOccupied;
- for (AkUInt32 uBaseSlot = 0; uBaseSlot < uNumReservedEntries; uBaseSlot += 8)
- {
- AkUInt64 slotOccMask = *(AkUInt64*)(pbSlotOccupied + uBaseSlot);
- while (slotOccMask)
- {
- AkUInt32 slotSubIdx = AKPLATFORM::AkBitScanReverse64(slotOccMask);
- in_func(uBaseSlot + 7 - (slotSubIdx / 8));
- slotOccMask ^= (0x8000000000000000ULL >> slotSubIdx);
- }
- }
- }
- }
- }
|