1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039 |
- #pragma once
- #include "BeefySysLib/Common.h"
- #include "BeefySysLib/util/BumpAllocator.h"
- NS_BF_BEGIN
- extern int sRadixMapCount;
- extern int sRootSize;
- extern int sMidSize;
- extern int sLeafSize;
- template <typename T>
- class RadixMap32
- {
- public:
- // Put 32 entries in the root and (2^BITS)/32 entries in each leaf.
- static const int BLOCK_SHIFT = 8;
- static const int BITS = 32 - BLOCK_SHIFT;
- static const int ROOT_BITS = 12;
- static const int ROOT_LENGTH = 1 << ROOT_BITS;
- static const int LEAF_BITS = BITS - ROOT_BITS;
- static const int LEAF_LENGTH = 1 << LEAF_BITS;
- struct Iterator
- {
- public:
- RadixMap32* mRadixMap;
- int mRootIdx;
- int mLeafIdx;
- public:
- Iterator()
- {
- }
- Iterator& operator++()
- {
- mLeafIdx++;
- while (true)
- {
- if (mLeafIdx == LEAF_LENGTH)
- {
- mLeafIdx = 0;
- mRootIdx++;
- while (true)
- {
- if (mRootIdx == ROOT_LENGTH)
- return *this;
- if (mRadixMap->mRoot[mRootIdx] != NULL)
- break;
- mRootIdx++;
- }
- }
- if (mRadixMap->mRoot[mRootIdx]->mValues[mLeafIdx] != NULL)
- return *this;
- mLeafIdx++;
- }
- return *this;
- }
- bool operator!=(const Iterator& itr) const
- {
- return (itr.mRootIdx != mRootIdx) || (itr.mLeafIdx != mLeafIdx);
- }
- bool operator==(const Iterator& itr) const
- {
- return (itr.mRootIdx == mRootIdx) && (itr.mLeafIdx == mLeafIdx);
- }
- T operator*()
- {
- return mRadixMap->mRoot[mRootIdx]->mValues[mLeafIdx];
- }
- };
- struct Leaf
- {
- T mValues[LEAF_LENGTH];
- T GetFirst(int startLeaf = 0)
- {
- for (int i = startLeaf; i < LEAF_LENGTH; i++)
- {
- auto value = mValues[i];
- if (value != NULL)
- {
- auto lowestValue = value;
- while (value != NULL)
- {
- if (value->mAddress < lowestValue->mAddress)
- lowestValue = value;
- value = value->mNext;
- }
- return lowestValue;
- }
- }
- return NULL;
- }
- };
- Leaf* mRoot[ROOT_LENGTH]; // Pointers to 32 child nodes
- typedef uint32 Number;
- public:
- RadixMap32()
- {
- memset(mRoot, 0, sizeof(mRoot));
- }
- ~RadixMap32()
- {
- int leafCount = 0;
- for (int i = 0; i < ROOT_LENGTH; i++)
- {
- if (mRoot[i] != NULL)
- {
- leafCount++;
- delete mRoot[i];
- }
- }
- }
- Iterator begin()
- {
- Iterator itr;
- itr.mRadixMap = this;
- itr.mRootIdx = -1;
- itr.mLeafIdx = LEAF_LENGTH - 1;
- return ++itr;
- }
- Iterator end()
- {
- Iterator itr;
- itr.mRadixMap = this;
- itr.mRootIdx = ROOT_LENGTH;
- itr.mLeafIdx = 0;
- return itr;
- }
- void Clear()
- {
- for (int i = 0; i < ROOT_LENGTH; i++)
- {
- if (mRoot[i] != NULL)
- {
- delete mRoot[i];
- mRoot[i] = NULL;
- }
- }
- }
- bool IsEmpty()
- {
- for (int i = 0; i < ROOT_LENGTH; i++)
- if (mRoot[i] != NULL)
- return false;
- return true;
- }
- T FindFirstLeafAt(Number addr)
- {
- int blockAddr = (int)(addr >> BLOCK_SHIFT);
- int i1 = (int)(blockAddr >> LEAF_BITS);
- int i2 = (int)(blockAddr & (LEAF_LENGTH - 1));
- Leaf* leaf = mRoot[i1];
- if (leaf == NULL)
- return NULL;
- return leaf->mValues[i2];
- }
- T Get(Number addr, int maxOffset = 0) const
- {
- int blockOffsetsLeft = (maxOffset + (1 << BLOCK_SHIFT) - 1) >> BLOCK_SHIFT;
- int blockAddr = (int)(addr >> BLOCK_SHIFT);
- int i1 = (int)(blockAddr >> LEAF_BITS);
- int i2 = (int)(blockAddr & (LEAF_LENGTH - 1));
- // Find closest entry to requested addr
- Leaf* leaf = mRoot[i1];
- int bestDist = 0x7FFFFFFF;
- T bestValue = NULL;
- if (leaf != NULL)
- {
- T curValue = leaf->mValues[i2];
- while (curValue != NULL)
- {
- if (addr >= curValue->mAddress)
- {
- int dist = (int)(addr - curValue->mAddress);
- if (dist < bestDist)
- {
- bestDist = dist;
- bestValue = curValue;
- }
- }
- curValue = curValue->mNext;
- }
- if ((bestValue != NULL) || (maxOffset == 0))
- return bestValue;
- }
- // Start searching for the highest address below the current i1:i2
- while (blockOffsetsLeft > 0)
- {
- blockOffsetsLeft--;
- i2--;
- if (i2 < 0)
- {
- i1--;
- if (i1 < 0)
- break;
- i2 = LEAF_LENGTH - 1;
- }
- leaf = mRoot[i1];
- if (leaf != NULL)
- {
- auto value = leaf->mValues[i2];
- if (value != NULL)
- {
- auto bestValue = value;
- while (value != NULL)
- {
- if (value->mAddress > bestValue->mAddress)
- bestValue = value;
- value = value->mNext;
- }
- return bestValue;
- }
- }
- }
- return NULL;
- }
- T GetNext(T value)
- {
- const Number blockAddr = value->mAddress >> BLOCK_SHIFT;
- const Number i1 = blockAddr >> LEAF_BITS;
- const Number i2 = blockAddr & (LEAF_LENGTH - 1);
- // Find closest entry to requested addr
- Leaf* leaf = mRoot[i1];
- if (leaf == NULL)
- return NULL;
- T curValue = leaf->mValues[i2];
- int bestDist = 0x7FFFFFFF;
- T bestValue = NULL;
- while (curValue != NULL)
- {
- if (curValue->mAddress > value->mAddress)
- {
- int dist = curValue->mAddress - value->mAddress;
- if (dist < bestDist)
- {
- bestDist = dist;
- bestValue = curValue;
- }
- }
- curValue = curValue->mNext;
- }
- if (bestValue != NULL)
- return bestValue;
- // Get lowest value in next leaf
- curValue = leaf->GetFirst(i2 + 1);
- while (curValue != NULL)
- {
- BF_ASSERT(curValue != value);
- if (curValue->mAddress > value->mAddress)
- {
- int dist = curValue->mAddress - value->mAddress;
- if (dist < bestDist)
- {
- bestDist = dist;
- bestValue = curValue;
- }
- }
- curValue = curValue->mNext;
- }
- if (bestValue != NULL)
- return bestValue;
- // Get first value in next root nodes
- for (int rootIdx = i1 + 1; rootIdx < ROOT_LENGTH; rootIdx++)
- {
- if (mRoot[rootIdx] != NULL)
- {
- curValue = mRoot[rootIdx]->GetFirst();
- if ((curValue != NULL) && (curValue->mAddress > value->mAddress))
- return curValue;
- }
- }
- return NULL;
- }
- T GetUnordered(Number addr, int maxReverseOffset) const
- {
- int blockOffsetsLeft = (maxReverseOffset + (1 << BLOCK_SHIFT) - 1) >> BLOCK_SHIFT;
- int blockAddr = (int)(addr >> BLOCK_SHIFT);
- int i1 = (int)(blockAddr >> LEAF_BITS);
- int i2 = (int)(blockAddr & (LEAF_LENGTH - 1));
- while (blockOffsetsLeft > 0)
- {
- Leaf* leaf = mRoot[i1];
- if (leaf != NULL)
- {
- auto value = leaf->mValues[i2];
- if (value != NULL)
- return value;
- i2++;
- if (i2 == LEAF_LENGTH)
- {
- i2 = 0;
- i1++;
- }
- blockOffsetsLeft--;
- }
- else
- {
- i1++;
- blockOffsetsLeft -= LEAF_LENGTH;
- }
- }
- return NULL;
- }
- void RemoveRange(Number startAddr, Number length)
- {
- Number endAddr = startAddr + length;
- int blockAddrStart = (int)(startAddr >> BLOCK_SHIFT);
- int blockAddrEnd = (int)(endAddr >> BLOCK_SHIFT);
- int i1Start = (int)(blockAddrStart >> LEAF_BITS);
- int i1End = (int)((blockAddrEnd - 1) >> LEAF_BITS) + 1;
- for (int i1 = i1Start; i1 < i1End; i1++)
- {
- Leaf* leaf = mRoot[i1];
- if (leaf == NULL)
- continue;
- int i2Start;
- int i2End;
- if (i1 == i1Start)
- {
- i2Start = (int)(blockAddrStart & (LEAF_LENGTH - 1));
- i2End = LEAF_LENGTH;
- }
- else if (i1 == i1End - 1)
- {
- i2Start = 0;
- i2End = (int)((blockAddrEnd - 1) & (LEAF_LENGTH - 1)) + 1;
- }
- else
- {
- i2Start = 0;
- i2End = LEAF_LENGTH;
- }
- for (int i2 = i2Start; i2 < i2End; i2++)
- {
- T curValue = leaf->mValues[i2];
- if (curValue == NULL)
- continue;
- T* nextPtr = &leaf->mValues[i2];
- while (curValue != NULL)
- {
- if ((curValue->mAddress >= startAddr) && (curValue->mAddress < endAddr))
- {
- // We're removing it implicitly
- }
- else
- {
- *nextPtr = curValue;
- nextPtr = &curValue->mNext;
- }
- curValue = curValue->mNext;
- }
- *nextPtr = NULL;
- }
- }
- }
- void Insert(T value)
- {
- const Number blockAddr = value->mAddress >> BLOCK_SHIFT;
- const Number i1 = blockAddr >> LEAF_BITS;
- const Number i2 = blockAddr & (LEAF_LENGTH - 1);
- Leaf* leaf = mRoot[i1];
- if (leaf == NULL)
- {
- leaf = new Leaf();
- sLeafSize += sizeof(Leaf);
- mRoot[i1] = leaf;
- }
- T prevValue = leaf->mValues[i2];
- mRoot[i1]->mValues[i2] = value;
- value->mNext = prevValue;
- }
- void Remove(T value)
- {
- const Number blockAddr = value->mAddress >> BLOCK_SHIFT;
- const Number i1 = blockAddr >> LEAF_BITS;
- const Number i2 = blockAddr & (LEAF_LENGTH - 1);
- // Find closest entry to requested addr
- Leaf* leaf = mRoot[i1];
- T prevValue = NULL;
- T curValue = leaf->mValues[i2];
- while (curValue != NULL)
- {
- if (curValue == value)
- {
- if (prevValue == NULL)
- leaf->mValues[i2] = curValue->mNext;
- else
- prevValue->mNext = curValue->mNext;
- curValue->mNext = NULL;
- return;
- }
- prevValue = curValue;
- curValue = curValue->mNext;
- }
- }
- };
- template <typename T>
- class RadixMap64
- {
- public:
- // Higher BLOCK_SHIFT causes more searches but reduces memory usage
- static const int BLOCK_SHIFT = 8;
- static const int BITS = 48 - BLOCK_SHIFT;
- static const int ROOT_BITS = 14;
- static const int ROOT_LENGTH = 1 << ROOT_BITS;
- static const int MID_BITS = 13;
- static const int MID_LENGTH = 1 << MID_BITS;
- static const int LEAF_BITS = BITS - ROOT_BITS - MID_BITS;
- static const int LEAF_LENGTH = 1 << LEAF_BITS;
- struct Iterator
- {
- public:
- RadixMap64* mRadixMap;
- int mRootIdx;
- int mMidIdx;
- int mLeafIdx;
- public:
- Iterator()
- {
- }
- Iterator& operator++()
- {
- mLeafIdx++;
- while (true)
- {
- if (mLeafIdx == LEAF_LENGTH)
- {
- mLeafIdx = 0;
- mMidIdx++;
- while (true)
- {
- if (mMidIdx == MID_LENGTH)
- {
- mMidIdx = 0;
- mRootIdx++;
- while (true)
- {
- if (mRootIdx == ROOT_LENGTH)
- return *this;
- if (mRadixMap->mRoot[mRootIdx] != NULL)
- break;
- mRootIdx++;
- }
- }
- if (mRadixMap->mRoot[mRootIdx]->mLeafs[mMidIdx] != NULL)
- break;
- mMidIdx++;
- }
- }
- if (mRadixMap->mRoot[mRootIdx]->mLeafs[mMidIdx]->mValues[mLeafIdx] != NULL)
- return *this;
- mLeafIdx++;
- }
- return *this;
- }
- bool operator!=(const Iterator& itr) const
- {
- return (itr.mRootIdx != mRootIdx) || (itr.mMidIdx != mMidIdx) || (itr.mLeafIdx != mLeafIdx);
- }
- bool operator==(const Iterator& itr) const
- {
- return (itr.mRootIdx == mRootIdx) && (itr.mMidIdx == mMidIdx) && (itr.mLeafIdx == mLeafIdx);
- }
- T operator*()
- {
- return mRadixMap->mRoot[mRootIdx]->mLeafs[mMidIdx]->mValues[mLeafIdx];
- }
- };
- struct Leaf
- {
- T mValues[LEAF_LENGTH];
- T GetFirst(int startLeaf = 0)
- {
- for (int i = startLeaf; i < LEAF_LENGTH; i++)
- {
- auto value = mValues[i];
- if (value != NULL)
- {
- auto lowestValue = value;
- while (value != NULL)
- {
- if (value->mAddress < lowestValue->mAddress)
- lowestValue = value;
- value = value->mNext;
- }
- return lowestValue;
- }
- }
- return NULL;
- }
- };
- struct Mid
- {
- Leaf* mLeafs[MID_LENGTH];
- ~Mid()
- {
- for (int i = 0; i < MID_LENGTH; i++)
- if (mLeafs[i] != NULL)
- delete mLeafs[i];
- }
- };
- Mid* mRoot[ROOT_LENGTH]; // Pointers to 32 child nodes
- typedef uint64 Number;
- int mAllocSize;
- public:
- RadixMap64()
- {
- memset(mRoot, 0, sizeof(mRoot));
- sRadixMapCount++;
- sRootSize += sizeof(RadixMap64);
- mAllocSize = sizeof(RadixMap64);
- }
- ~RadixMap64()
- {
- int leafCount = 0;
- for (int i = 0; i < ROOT_LENGTH; i++)
- {
- if (mRoot[i] != NULL)
- {
- leafCount++;
- delete mRoot[i];
- }
- }
- }
- Iterator begin()
- {
- Iterator itr;
- itr.mRadixMap = this;
- itr.mRootIdx = -1;
- itr.mMidIdx = MID_LENGTH - 1;
- itr.mLeafIdx = LEAF_LENGTH - 1;
- return ++itr;
- }
- Iterator end()
- {
- Iterator itr;
- itr.mRadixMap = this;
- itr.mRootIdx = ROOT_LENGTH;
- itr.mMidIdx = 0;
- itr.mLeafIdx = 0;
- return itr;
- }
- void Clear()
- {
- for (int i = 0; i < ROOT_LENGTH; i++)
- {
- if (mRoot[i] != NULL)
- {
- delete mRoot[i];
- mRoot[i] = NULL;
- }
- }
- }
- bool IsEmpty()
- {
- for (int i = 0; i < ROOT_LENGTH; i++)
- if (mRoot[i] != NULL)
- return false;
- return true;
- }
- T FindFirstLeafAt(Number addr)
- {
- if ((addr & 0xFFFF000000000000LL) != 0)
- {
- return T();
- }
- int64 blockAddr = (int64)(addr >> BLOCK_SHIFT);
- int i1 = (int)(blockAddr >> (LEAF_BITS + MID_BITS));
- int i2 = (int)((blockAddr >> LEAF_BITS) & (MID_LENGTH - 1));
- int i3 = (int)(blockAddr & (LEAF_LENGTH - 1));
- Mid* mid = mRoot[i1];
- if (mid == NULL)
- return NULL;
- Leaf* leaf = mid->mLeafs[i2];
- if (leaf == NULL)
- return NULL;
- return leaf->mValues[i3];
- }
- T Get(Number addr, int maxOffset = 0) const
- {
- if ((addr & 0xFFFF000000000000LL) != 0)
- {
- // On overflow return default
- return T();
- }
- int blockOffsetsLeft = (maxOffset + (1 << BLOCK_SHIFT) - 1) >> BLOCK_SHIFT;
- int64 blockAddr = (int64)(addr >> BLOCK_SHIFT);
- int i1 = (int)(blockAddr >> (LEAF_BITS + MID_BITS));
- int i2 = (int)((blockAddr >> LEAF_BITS) & (MID_LENGTH - 1));
- int i3 = (int)(blockAddr & (LEAF_LENGTH - 1));
- // Find closest entry to requested addr
- Mid* mid = mRoot[i1];
- Leaf* leaf = NULL;
- if (mid != NULL)
- leaf = mid->mLeafs[i2];
- int bestDist = 0x7FFFFFFF;
- T bestValue = NULL;
- if (leaf != NULL)
- {
- T curValue = leaf->mValues[i3];
- while (curValue != NULL)
- {
- if (addr >= curValue->mAddress)
- {
- int dist = (int)(addr - curValue->mAddress);
- if (dist < bestDist)
- {
- bestDist = dist;
- bestValue = curValue;
- }
- }
- curValue = curValue->mNext;
- }
- if ((bestValue != NULL) || (maxOffset == 0))
- return bestValue;
- }
- // Start searching for the highest address below the current i1:i2
- while (blockOffsetsLeft > 0)
- {
- blockOffsetsLeft--;
- i3--;
- if (i3 < 0)
- {
- i2--;
- if (i2 < 0)
- {
- i1--;
- if (i1 < 0)
- break;
- i2 = MID_LENGTH - 1;
- }
- i3 = LEAF_LENGTH - 1;
- }
- mid = mRoot[i1];
- if (mid != NULL)
- {
- leaf = mid->mLeafs[i2];
- if (leaf != NULL)
- {
- auto value = leaf->mValues[i3];
- if (value != NULL)
- {
- auto bestValue = value;
- while (value != NULL)
- {
- if (value->mAddress > bestValue->mAddress)
- bestValue = value;
- value = value->mNext;
- }
- return bestValue;
- }
- }
- }
- }
- return NULL;
- }
- T GetNext(T value)
- {
- const Number blockAddr = value->mAddress >> BLOCK_SHIFT;
- int i1 = (int)(blockAddr >> (LEAF_BITS + MID_BITS));
- int i2 = (int)((blockAddr >> LEAF_BITS) & (MID_LENGTH - 1));
- int i3 = (int)(blockAddr & (LEAF_LENGTH - 1));
- // Find closest entry to requested addr
- Mid* mid = mRoot[i1];
- if (mid == NULL)
- return NULL;
- Leaf* leaf = mid->mLeafs[i2];
- if (leaf == NULL)
- return NULL;
- T curValue = leaf->mValues[i3];
- int bestDist = 0x7FFFFFFF;
- T bestValue = NULL;
- while (curValue != NULL)
- {
- if (curValue->mAddress > value->mAddress)
- {
- int dist = curValue->mAddress - value->mAddress;
- if (dist < bestDist)
- {
- bestDist = dist;
- bestValue = curValue;
- }
- }
- curValue = curValue->mNext;
- }
- if (bestValue != NULL)
- return bestValue;
- // Get lowest value in next leaf
- curValue = leaf->GetFirst(i2 + 1);
- while (curValue != NULL)
- {
- BF_ASSERT(curValue != value);
- if (curValue->mAddress > value->mAddress)
- {
- int dist = curValue->mAddress - value->mAddress;
- if (dist < bestDist)
- {
- bestDist = dist;
- bestValue = curValue;
- }
- }
- curValue = curValue->mNext;
- }
- if (bestValue != NULL)
- return bestValue;
- for (int midIdx = i2 + 1; midIdx < MID_LENGTH; midIdx++)
- {
- if (mid->mLeafs[midIdx] != NULL)
- {
- curValue = mid->mLeafs[midIdx]->GetFirst();
- if ((curValue != NULL) && (curValue->mAddress > value->mAddress))
- return curValue;
- }
- }
- // Get first value in next root nodes
- for (int rootIdx = i1 + 1; rootIdx < ROOT_LENGTH; rootIdx++)
- {
- if (mRoot[rootIdx] != NULL)
- {
- mid = mRoot[rootIdx];
- for (int midIdx = 0; midIdx < MID_LENGTH; midIdx++)
- {
- curValue = mid->mLeafs[midIdx]->GetFirst();
- if ((curValue != NULL) && (curValue->mAddress > value->mAddress))
- return curValue;
- }
- }
- }
- return NULL;
- }
- void RemoveRange(Number startAddr, Number length)
- {
- Number endAddr = BF_MIN(startAddr + length, 0x0001000000000000LL);
- startAddr = BF_MIN(startAddr, 0x0000FFFFFFFFFFFFLL);
- Number blockAddrStart = startAddr >> BLOCK_SHIFT;
- Number blockAddrEnd = endAddr >> BLOCK_SHIFT;
- int i1Start = (int)(blockAddrStart >> (LEAF_BITS + MID_BITS));
- int i1End = (int)((blockAddrEnd - 1) >> (LEAF_BITS + MID_BITS)) + 1;
- for (int i1 = i1Start; i1 < i1End; i1++)
- {
- Mid* mid = mRoot[i1];
- if (mid == NULL)
- continue;
- int i2Start;
- int i2End;
- if (i1 == i1Start)
- {
- i2Start = (int)((blockAddrStart >> LEAF_BITS) & (MID_LENGTH - 1));
- i2End = MID_LENGTH;
- }
- else if (i1 == i1End)
- {
- i2Start = 0;
- i2End = (int)(((blockAddrEnd - 1) >> LEAF_BITS) & (MID_LENGTH - 1)) + 1;
- }
- else
- {
- i2Start = 0;
- i2End = MID_LENGTH;
- }
- for (int i2 = i2Start; i2 < i2End; i2++)
- {
- Leaf* leaf = mid->mLeafs[i2];
- if (leaf == NULL)
- continue;
- int i3Start;
- int i3End;
- if ((i1 == i1Start) && (i2 == i2Start))
- {
- i3Start = (int)(blockAddrStart & (LEAF_LENGTH - 1));
- i3End = LEAF_LENGTH;
- }
- else if ((i1 == i1End - 1) && (i2 == i2End - 1))
- {
- i3Start = 0;
- i3End = (int)((blockAddrEnd - 1) & (LEAF_LENGTH - 1)) + 1;
- }
- else
- {
- i3Start = 0;
- i3End = LEAF_LENGTH;
- }
- for (int i3 = i3Start; i3 < i3End; i3++)
- {
- T curValue = leaf->mValues[i3];
- if (curValue == NULL)
- continue;
- T* nextPtr = &leaf->mValues[i3];
- while (curValue != NULL)
- {
- if ((curValue->mAddress >= startAddr) && (curValue->mAddress < endAddr))
- {
- // We're removing it implicitly
- }
- else
- {
- *nextPtr = curValue;
- nextPtr = &curValue->mNext;
- }
- curValue = curValue->mNext;
- }
- *nextPtr = NULL;
- }
- }
- }
- }
- T GetUnordered(Number addr, int maxOffset) const
- {
- if ((addr & 0xFFFF000000000000LL) != 0)
- {
- return T();
- }
- int blockOffsetsLeft = (maxOffset + (1 << BLOCK_SHIFT) - 1) >> BLOCK_SHIFT;
- const Number blockAddr = addr >> BLOCK_SHIFT;
- int i1 = (int)(blockAddr >> (LEAF_BITS + MID_BITS));
- int i2 = (int)((blockAddr >> LEAF_BITS) & (MID_LENGTH - 1));
- int i3 = (int)(blockAddr & (LEAF_LENGTH - 1));
- while (blockOffsetsLeft > 0)
- {
- Mid* mid = mRoot[i1];
- if (mid != NULL)
- {
- Leaf* leaf = mid->mLeafs[i2];
- if (leaf != NULL)
- {
- auto value = leaf->mValues[i3];
- if (value != NULL)
- return value;
- i3++;
- if (i3 == LEAF_LENGTH)
- {
- i3 = 0;
- i2++;
- if (i2 == MID_LENGTH)
- {
- i2 = 0;
- i1++;
- }
- }
- blockOffsetsLeft--;
- }
- else
- {
- i2++;
- blockOffsetsLeft -= LEAF_LENGTH;
- }
- }
- else
- {
- // MID_LENGTH * LEAF_LENGTH is > 4GB, so a mRoot[i1] being NULL indicates no data
- return NULL;
- }
- }
- return NULL;
- }
- T GetNextUnordered(T value, int maxOffset) const
- {
- if (value->mNext != NULL)
- return value->mNext;
- return GetUnordered(value->mAddress + 1, maxOffset - 1);
- }
- void Insert(T value)
- {
- BF_ASSERT((value->mAddress & 0xFFFF000000000000LL) == 0);
- const Number blockAddr = value->mAddress >> BLOCK_SHIFT;
- int i1 = (int)(blockAddr >> (LEAF_BITS + MID_BITS));
- int i2 = (int)((blockAddr >> LEAF_BITS) & (MID_LENGTH - 1));
- int i3 = (int)(blockAddr & (LEAF_LENGTH - 1));
- BF_ASSERT((i1 >= 0) && (i1 < ROOT_LENGTH));
- Mid* mid = mRoot[i1];
- if (mid == NULL)
- {
- mid = new Mid();
- mAllocSize += sizeof(Mid);
- sMidSize += sizeof(Mid);
- mRoot[i1] = mid;
- }
- BF_ASSERT((i2 >= 0) && (i2 < MID_LENGTH));
- Leaf* leaf = mid->mLeafs[i2];
- if (leaf == NULL)
- {
- leaf = new Leaf();
- sLeafSize += sizeof(Leaf);
- mAllocSize += sizeof(Leaf);
- mid->mLeafs[i2] = leaf;
- }
- T prevValue = leaf->mValues[i3];
- leaf->mValues[i3] = value;
- value->mNext = prevValue;
- }
- void Remove(T value)
- {
- const Number blockAddr = value->mAddress >> BLOCK_SHIFT;
- int i1 = (int)(blockAddr >> (LEAF_BITS + MID_BITS));
- int i2 = (int)((blockAddr >> LEAF_BITS) & (MID_LENGTH - 1));
- int i3 = (int)(blockAddr & (LEAF_LENGTH - 1));
- // Find closest entry to requested addr
- Mid* mid = mRoot[i1];
- Leaf* leaf = mid->mLeafs[i2];
- T prevValue = NULL;
- T curValue = leaf->mValues[i3];
- while (curValue != NULL)
- {
- if (curValue == value)
- {
- if (prevValue == NULL)
- leaf->mValues[i3] = curValue->mNext;
- else
- prevValue->mNext = curValue->mNext;
- curValue->mNext = NULL;
- return;
- }
- prevValue = curValue;
- curValue = curValue->mNext;
- }
- }
- };
- NS_BF_END
|