From 1565c72f07762a6ffe2a57466bb57cf039f86598 Mon Sep 17 00:00:00 2001 From: Mia McMahill <84749759+electricbrass@users.noreply.github.com> Date: Tue, 17 Dec 2024 02:43:37 -0600 Subject: [PATCH 1/7] Reinitialize states, sprites, and mobjinfo from full contents of backup Also changes a number of instances of iteration over DoomObjContainers to use iterators --- client/src/cl_level.cpp | 18 +++++++++--------- common/d_dehacked.cpp | 15 ++++++++++++--- common/p_pspr.cpp | 2 +- server/src/sv_level.cpp | 38 +++++++++++++++++++++----------------- 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/client/src/cl_level.cpp b/client/src/cl_level.cpp index 4c78015a2..d1c0b0250 100644 --- a/client/src/cl_level.cpp +++ b/client/src/cl_level.cpp @@ -239,17 +239,17 @@ void G_InitNew (const char *mapname) { if (wantFast) { - for (i = 0; i < ::num_state_t_types(); i++) + for (const auto& it : states) { - state_t* state = states[i]; + state_t* state = it.second; if (state->flags & STATEF_SKILL5FAST && (state->tics != 1 || demoplayback)) state->tics >>= 1; // don't change 1->0 since it causes cycles } - for (i = 0; i < ::num_mobjinfo_types(); ++i) + for (const auto& it : mobjinfo) { - mobjinfo_t* minfo = mobjinfo[i]; + mobjinfo_t* minfo = it.second; if (minfo->altspeed != NO_ALTSPEED) { int swap = minfo->speed; @@ -260,16 +260,16 @@ void G_InitNew (const char *mapname) } else { - for (i = 0; i < ::num_state_t_types(); i++) + for (const auto& it : states) { - state_t* state = states[i]; + state_t* state = it.second; if (state->flags & STATEF_SKILL5FAST) state->tics <<= 1; // don't change 1->0 since it causes cycles } - for (i = 0; i < ::num_mobjinfo_types(); ++i) + for (const auto& it : mobjinfo) { - mobjinfo_t* minfo = mobjinfo[i]; + mobjinfo_t* minfo = it.second; if (minfo->altspeed != NO_ALTSPEED) { int swap = minfo->altspeed; @@ -301,7 +301,7 @@ void G_InitNew (const char *mapname) viewactive = true; D_SetupUserInfo(); - + level.mapname = mapname; // [AM}] WDL stats (for testing purposes) diff --git a/common/d_dehacked.cpp b/common/d_dehacked.cpp index aa9d9f729..c7db8a6b9 100644 --- a/common/d_dehacked.cpp +++ b/common/d_dehacked.cpp @@ -551,6 +551,7 @@ typedef struct DoomObjectContainer backupMobjInfo; // doom_mobjinfo DoomObjectContainer backupSprnames; // doom_sprnames DoomObjectContainer backupSoundMap; // doom_SoundMap + std::vector backupS_sfx; weaponinfo_t backupWeaponInfo[NUMWEAPONS + 1]; int backupMaxAmmo[NUMAMMO]; int backupClipAmmo[NUMAMMO]; @@ -628,6 +629,7 @@ static void BackupData(void) std::copy(clipammo, clipammo + ::NUMAMMO, doomBackup.backupClipAmmo); std::copy(maxammo, maxammo + ::NUMAMMO, doomBackup.backupMaxAmmo); doomBackup.backupDeh = deh; + doomBackup.backupS_sfx = S_sfx; BackedUpData = true; } @@ -653,10 +655,16 @@ void D_UndoDehPatch() } M_Free(OrgSprNames); + + sprnames.clear(); + sprnames.reserve(doomBackup.backupSprnames.size()); + for (const auto& sprname : doomBackup.backupSprnames) + { + sprnames.insert(sprname.second, sprname.first); + } // unsafe usage of data() here but to keep a consistent API - D_Initialize_sprnames(doomBackup.backupSprnames.data(), ::NUMSPRITES, SPR_TROO); - D_Initialize_States(doomBackup.backupStates.data(), ::NUMSTATES); - D_Initialize_Mobjinfo(doomBackup.backupMobjInfo.data(), ::NUMMOBJTYPES); + D_Initialize_States(doomBackup.backupStates.data(), doomBackup.backupStates.size()); + D_Initialize_Mobjinfo(doomBackup.backupMobjInfo.data(), doomBackup.backupMobjInfo.size()); D_Initialize_SoundMap(doomBackup.backupSoundMap.data(), ARRAY_LENGTH(doom_SoundMap)); extern bool isFast; @@ -668,6 +676,7 @@ void D_UndoDehPatch() std::copy(doomBackup.backupMaxAmmo, doomBackup.backupMaxAmmo + ::NUMAMMO, maxammo); deh = doomBackup.backupDeh; + S_sfx = doomBackup.backupS_sfx; BackedUpData = false; } diff --git a/common/p_pspr.cpp b/common/p_pspr.cpp index 352d63993..6cd6724f5 100644 --- a/common/p_pspr.cpp +++ b/common/p_pspr.cpp @@ -185,7 +185,7 @@ void P_SetPspritePtr(player_t* player, pspdef_t* psp, int32_t stnum) break; } - if (stnum >= ::num_state_t_types()) + if (states.find(stnum) == states.end()) return; psp->state = states[stnum]; diff --git a/server/src/sv_level.cpp b/server/src/sv_level.cpp index f1d263e66..a6d91d3eb 100644 --- a/server/src/sv_level.cpp +++ b/server/src/sv_level.cpp @@ -422,38 +422,42 @@ void G_InitNew(const char *mapname) { if (wantFast) { - for (i = 0; i < ::num_state_t_types(); i++) + for (const auto& it : states) { - if (states[i]->flags & STATEF_SKILL5FAST && - (states[i]->tics != 1 || demoplayback)) - states[i]->tics >>= 1; // don't change 1->0 since it causes cycles + state_t* state = it.second; + if (state->flags & STATEF_SKILL5FAST && + (state->tics != 1 || demoplayback)) + state->tics >>= 1; // don't change 1->0 since it causes cycles } - for (i = 0; i < ::num_mobjinfo_types(); ++i) + for (const auto& it : mobjinfo) { - if (mobjinfo[i]->altspeed != NO_ALTSPEED) + mobjinfo_t* minfo = it.second; + if (minfo->altspeed != NO_ALTSPEED) { - int swap = mobjinfo[i]->speed; - mobjinfo[i]->speed = mobjinfo[i]->altspeed; - mobjinfo[i]->altspeed = swap; + int swap = minfo->speed; + minfo->speed = minfo->altspeed; + minfo->altspeed = swap; } } } else { - for (i = 0; i < ::num_state_t_types(); i++) + for (const auto& it : states) { - if (states[i]->flags & STATEF_SKILL5FAST) - states[i]->tics <<= 1; // don't change 1->0 since it causes cycles + state_t* state = it.second; + if (state->flags & STATEF_SKILL5FAST) + state->tics <<= 1; // don't change 1->0 since it causes cycles } - for (i = 0; i < ::num_mobjinfo_types(); ++i) + for (const auto& it : mobjinfo) { - if (mobjinfo[i]->altspeed != NO_ALTSPEED) + mobjinfo_t* minfo = it.second; + if (minfo->altspeed != NO_ALTSPEED) { - int swap = mobjinfo[i]->altspeed; - mobjinfo[i]->altspeed = mobjinfo[i]->speed; - mobjinfo[i]->speed = swap; + int swap = minfo->altspeed; + minfo->altspeed = minfo->speed; + minfo->speed = swap; } } } From a5a0b965fea93090fc3dec3cc38331a0429cfc9d Mon Sep 17 00:00:00 2001 From: Mia McMahill <84749759+electricbrass@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:56:19 -0600 Subject: [PATCH 2/7] Call S_ClearSoundLumps in D_Shutdown instead of in S_ParseSndInfo --- client/src/d_main.cpp | 1 + client/src/s_sound.cpp | 2 -- server/src/d_main.cpp | 1 + server/src/s_sound.cpp | 6 ++---- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/client/src/d_main.cpp b/client/src/d_main.cpp index a54681bd0..586a45367 100644 --- a/client/src/d_main.cpp +++ b/client/src/d_main.cpp @@ -711,6 +711,7 @@ void STACK_ARGS D_Shutdown() // stop sound effects and music S_Stop(); S_Deinit(); + S_ClearSoundLumps(); // shutdown automap AM_Stop(); diff --git a/client/src/s_sound.cpp b/client/src/s_sound.cpp index 842a7fe69..189064a74 100644 --- a/client/src/s_sound.cpp +++ b/client/src/s_sound.cpp @@ -1279,8 +1279,6 @@ void S_AddRandomSound(int owner, std::vector& list) // Parses all loaded SNDINFO lumps. void S_ParseSndInfo() { - S_ClearSoundLumps(); - int lump = -1; while ((lump = W_FindLump("SNDINFO", lump)) != -1) { diff --git a/server/src/d_main.cpp b/server/src/d_main.cpp index bb1bdc91f..cea504078 100644 --- a/server/src/d_main.cpp +++ b/server/src/d_main.cpp @@ -202,6 +202,7 @@ void STACK_ARGS D_Shutdown() // stop sound effects and music S_Stop(); + S_ClearSoundLumps(); DThinker::DestroyAllThinkers(); diff --git a/server/src/s_sound.cpp b/server/src/s_sound.cpp index 20c0b3713..976307ce4 100644 --- a/server/src/s_sound.cpp +++ b/server/src/s_sound.cpp @@ -1,4 +1,4 @@ -// Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id$ @@ -258,7 +258,7 @@ int S_FindSound(const char *logicalname) int S_FindSoundByLump(int lump) { - if (lump != -1) + if (lump != -1) { for (unsigned i = 0; i < S_sfx.size(); i++) if (S_sfx[i].lumpnum == lump) @@ -341,8 +341,6 @@ void S_AddRandomSound(int owner, std::vector& list) // Parses all loaded SNDINFO lumps. void S_ParseSndInfo() { - S_ClearSoundLumps(); - int lump = -1; while ((lump = W_FindLump("SNDINFO", lump)) != -1) { From 76b46982d104eb5902d7b193f16ddf2fdc7784b5 Mon Sep 17 00:00:00 2001 From: Mia McMahill <84749759+electricbrass@users.noreply.github.com> Date: Wed, 18 Dec 2024 01:04:30 -0600 Subject: [PATCH 3/7] Clean up some compiler warnings --- common/d_dehacked.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/d_dehacked.cpp b/common/d_dehacked.cpp index c7db8a6b9..7eae7c325 100644 --- a/common/d_dehacked.cpp +++ b/common/d_dehacked.cpp @@ -663,9 +663,9 @@ void D_UndoDehPatch() sprnames.insert(sprname.second, sprname.first); } // unsafe usage of data() here but to keep a consistent API - D_Initialize_States(doomBackup.backupStates.data(), doomBackup.backupStates.size()); - D_Initialize_Mobjinfo(doomBackup.backupMobjInfo.data(), doomBackup.backupMobjInfo.size()); - D_Initialize_SoundMap(doomBackup.backupSoundMap.data(), ARRAY_LENGTH(doom_SoundMap)); + D_Initialize_States(doomBackup.backupStates.data(), static_cast(doomBackup.backupStates.size())); + D_Initialize_Mobjinfo(doomBackup.backupMobjInfo.data(), static_cast(doomBackup.backupMobjInfo.size())); + D_Initialize_SoundMap(doomBackup.backupSoundMap.data(), static_cast(doomBackup.backupSoundMap.size())); extern bool isFast; isFast = false; From 7aa52421db33fd6dee88f0891b0f065c74e6605d Mon Sep 17 00:00:00 2001 From: Mia McMahill <84749759+electricbrass@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:25:13 -0600 Subject: [PATCH 4/7] Update D_PostProcessDeh --- common/d_dehacked.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/common/d_dehacked.cpp b/common/d_dehacked.cpp index 7eae7c325..17cbbcf3b 100644 --- a/common/d_dehacked.cpp +++ b/common/d_dehacked.cpp @@ -2738,43 +2738,41 @@ static CodePtr null_bexptr = {"(NULL)", NULL, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; void D_PostProcessDeh() { - int i, j; + int i; const CodePtr* bexptr_match; - int num_state_t_types = ::num_state_t_types(); - // [CMB] TODO: using ptr here is just to go from front to back - iterator is BETTER but this works - state_t** statesptr = states.data(); - for (i = 0; i < num_state_t_types; i++) + for (const auto& it : states) { + state_t* state = it.second; bexptr_match = &null_bexptr; - for (j = 1; CodePtrs[j].func != NULL; ++j) + for (i = 1; CodePtrs[i].func != NULL; ++i) { - if (statesptr[i]->action == CodePtrs[j].func) + if (state->action == CodePtrs[i].func) { - bexptr_match = &CodePtrs[j]; + bexptr_match = &CodePtrs[i]; break; } } // ensure states don't use more mbf21 args than their // action pointer expects, for future-proofing's sake - for (j = MAXSTATEARGS - 1; j >= bexptr_match->argcount; j--) + for (i = MAXSTATEARGS - 1; i >= bexptr_match->argcount; i--) { - if (statesptr[i]->args[j] != 0) + if (state->args[i] != 0) { I_Error("Action %s on state %d expects no more than %d nonzero args (%d " "found). Check your DEHACKED.", - bexptr_match->name, i, bexptr_match->argcount, j + 1); + bexptr_match->name, state->statenum, bexptr_match->argcount, i + 1); } } // replace unset fields with default values - for (; j >= 0; j--) + for (; i >= 0; i--) { - if (statesptr[i]->args[j] == 0 && bexptr_match->default_args[j]) + if (state->args[i] == 0 && bexptr_match->default_args[i]) { - statesptr[i]->args[j] = bexptr_match->default_args[j]; + state->args[i] = bexptr_match->default_args[i]; } } } From 7e5129d3f7d2d4bf6776ccda7f44540ba8382722 Mon Sep 17 00:00:00 2001 From: Mia McMahill <84749759+electricbrass@users.noreply.github.com> Date: Wed, 18 Dec 2024 19:50:24 -0600 Subject: [PATCH 5/7] More cleanup of usage of DoomObjectContainers, changed LookupTable type to std::unordered_map --- common/d_dehacked.cpp | 31 +++++++------------------------ common/doom_obj_container.h | 6 ++++-- common/p_mobj.cpp | 8 ++++---- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/common/d_dehacked.cpp b/common/d_dehacked.cpp index 17cbbcf3b..73fccc4ac 100644 --- a/common/d_dehacked.cpp +++ b/common/d_dehacked.cpp @@ -532,26 +532,12 @@ static BOOL HandleKey(const struct Key* keys, void* structure, const char* key, return true; } -/* -typedef struct -{ - state_t backupStates[::NUMSTATES]; - mobjinfo_t backupMobjInfo[::NUMMOBJTYPES]; - weaponinfo_t backupWeaponInfo[NUMWEAPONS + 1]; - const char** backupSprnames; - int backupMaxAmmo[NUMAMMO]; - int backupClipAmmo[NUMAMMO]; - DehInfo backupDeh; -} DoomBackup; -*/ - typedef struct { DoomObjectContainer backupStates; // boomstates DoomObjectContainer backupMobjInfo; // doom_mobjinfo DoomObjectContainer backupSprnames; // doom_sprnames DoomObjectContainer backupSoundMap; // doom_SoundMap - std::vector backupS_sfx; weaponinfo_t backupWeaponInfo[NUMWEAPONS + 1]; int backupMaxAmmo[NUMAMMO]; int backupClipAmmo[NUMAMMO]; @@ -590,8 +576,8 @@ static void BackupData(void) } // states - doomBackup.backupStates.resize(::NUMSTATES); doomBackup.backupStates.clear(); + doomBackup.backupStates.reserve(states.size()); for (const std::pair & it : states) { state_t state = *it.second; @@ -599,8 +585,8 @@ static void BackupData(void) } // mobjinfo - doomBackup.backupMobjInfo.resize(::NUMMOBJTYPES); doomBackup.backupMobjInfo.clear(); + doomBackup.backupMobjInfo.reserve(mobjinfo.size()); for (const std::pair & it : mobjinfo) { mobjinfo_t mobj = *it.second; @@ -608,8 +594,8 @@ static void BackupData(void) } // sprites - doomBackup.backupSprnames.resize(::NUMSPRITES); doomBackup.backupSprnames.clear(); + doomBackup.backupSprnames.reserve(sprnames.size()); for(const std::pair & it : sprnames) { const char* spr = strdup(it.second); @@ -617,8 +603,8 @@ static void BackupData(void) } // sounds - doomBackup.backupSoundMap.resize(ARRAY_LENGTH(doom_SoundMap)); doomBackup.backupSoundMap.clear(); + doomBackup.backupSoundMap.reserve(SoundMap.size()); for(const std::pair & it : SoundMap) { const char* sound = strdup(it.second); @@ -629,7 +615,6 @@ static void BackupData(void) std::copy(clipammo, clipammo + ::NUMAMMO, doomBackup.backupClipAmmo); std::copy(maxammo, maxammo + ::NUMAMMO, doomBackup.backupMaxAmmo); doomBackup.backupDeh = deh; - doomBackup.backupS_sfx = S_sfx; BackedUpData = true; } @@ -676,7 +661,6 @@ void D_UndoDehPatch() std::copy(doomBackup.backupMaxAmmo, doomBackup.backupMaxAmmo + ::NUMAMMO, maxammo); deh = doomBackup.backupDeh; - S_sfx = doomBackup.backupS_sfx; BackedUpData = false; } @@ -2061,12 +2045,11 @@ static int PatchPointer(int ptrNum) int i = atoi(Line2); // [CMB]: dsdhacked allows infinite code pointers - // if (i >= ::num_state_t_types()) + // is patchpointer supported at all for dsdhacked or does it only work for the original set of states, its deprecated in bex anyway if (states.find(i) == states.end()) { - DPrintf("Pointer %d overruns array (max: %d wanted: %d)." - "\n", - ptrNum, ::num_state_t_types(), i); + DPrintf("Source frame %d not found while patching pointer %d.\n", + i, ptrNum); } else { diff --git a/common/doom_obj_container.h b/common/doom_obj_container.h index 1acc1071a..cb6f556c9 100644 --- a/common/doom_obj_container.h +++ b/common/doom_obj_container.h @@ -12,7 +12,7 @@ #include "info.h" // doom object definitions - including enums with negative indices /* -extern state_t odastates[]; //statenum_t +extern state_t odastates[]; //statenum_t extern mobjinfo_t odathings[]; //mobjtype_t extern const char* odasprnames[]; // spritenum_t @@ -26,6 +26,7 @@ const char* D_GetOdaSprName(spritenum_t spritenum); #include #include #include +#include template class DoomObjectContainer; @@ -43,7 +44,7 @@ template LookupTable; + typedef std::unordered_map LookupTable; typedef InOrderContainer DoomObjectContainerData; typedef DoomObjectContainer DoomObjectContainerType; @@ -215,6 +216,7 @@ void DoomObjectContainer::clear() { this->container.erase(container.begin(), container.end()); this->lookup_table.erase(lookup_table.begin(), lookup_table.end()); + // this->lookup_table.clear(); // needed if we use OHashTable, maybe a bug with its implementation of erase? } // Allocation changes diff --git a/common/p_mobj.cpp b/common/p_mobj.cpp index 9a47128b0..9433c4401 100644 --- a/common/p_mobj.cpp +++ b/common/p_mobj.cpp @@ -3268,16 +3268,16 @@ BEGIN_COMMAND(cheat_mobjs) const char* mobj_type = argv[1]; ptrdiff_t mobj_index = -1; - // [CMB] TODO: should we use an iterator here? - for (size_t i = 0; i < ::num_mobjinfo_types(); i++) + for (const auto& it : mobjinfo) { - if (stricmp(::mobjinfo[i]->name, mobj_type) == 0) + if (stricmp(it.second->name, mobj_type) == 0) { - mobj_index = i; + mobj_index = it.first; break; } } + // TODO: index < 0 is valid now with dsdhacked if (mobj_index < 0) { Printf("Unknown MT_* mobj type\n"); From 85b888defa43b8b8cb4a5a53c75354f410660a6e Mon Sep 17 00:00:00 2001 From: Mia McMahill <84749759+electricbrass@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:04:27 -0600 Subject: [PATCH 6/7] Revert DoomObjectContainer to using OHashTable, clear with clear because it isn't buggy like erase and is more efficient --- common/doom_obj_container.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/common/doom_obj_container.h b/common/doom_obj_container.h index cb6f556c9..7112eb66e 100644 --- a/common/doom_obj_container.h +++ b/common/doom_obj_container.h @@ -26,7 +26,6 @@ const char* D_GetOdaSprName(spritenum_t spritenum); #include #include #include -#include template class DoomObjectContainer; @@ -44,7 +43,7 @@ template LookupTable; + typedef OHashTable LookupTable; typedef InOrderContainer DoomObjectContainerData; typedef DoomObjectContainer DoomObjectContainerType; @@ -214,9 +213,8 @@ size_t DoomObjectContainer::capacity() const template void DoomObjectContainer::clear() { - this->container.erase(container.begin(), container.end()); - this->lookup_table.erase(lookup_table.begin(), lookup_table.end()); - // this->lookup_table.clear(); // needed if we use OHashTable, maybe a bug with its implementation of erase? + this->container.clear(); + this->lookup_table.clear(); } // Allocation changes From 6e08da72a87abda2c8308977360d09786912d50c Mon Sep 17 00:00:00 2001 From: Mia McMahill <84749759+electricbrass@users.noreply.github.com> Date: Wed, 18 Dec 2024 23:27:32 -0600 Subject: [PATCH 7/7] Don't invalide iterators in OHashTable::erase(iterator it1, iterator it2) --- common/hashtable.h | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/common/hashtable.h b/common/hashtable.h index a53e1b315..5d5c5dd81 100644 --- a/common/hashtable.h +++ b/common/hashtable.h @@ -177,7 +177,7 @@ static inline unsigned int __hash_cstring(const char* str) unsigned int val = 0; while (*str != 0) val = val * 101 + *str++; - return val; + return val; } template <> struct hashfunc @@ -273,7 +273,7 @@ class OHashTable do { mBucketNum++; } while (mBucketNum < mHashTable->mSize && mHashTable->emptyBucket(mBucketNum)); - + if (mBucketNum >= mHashTable->mSize) mBucketNum = IHTT::NOT_FOUND; return *this; @@ -379,7 +379,7 @@ class OHashTable inline const_iterator end() const { return const_iterator(NOT_FOUND, this); - } + } inline iterator find(const KT& key) { @@ -407,7 +407,7 @@ class OHashTable std::pair insert(const HashPairType& hp) { - unsigned int oldused = mUsed; + unsigned int oldused = mUsed; IndexType bucketnum = insertElement(hp.first, hp.second); return std::pair(iterator(bucketnum, this), mUsed > oldused); } @@ -424,7 +424,7 @@ class OHashTable void erase(iterator it) { - eraseBucket(it.mBucketNum); + eraseBucket(it.mBucketNum); } unsigned int erase(const KT& key) @@ -440,9 +440,30 @@ class OHashTable { while (it1 != it2) { - eraseBucket(it1.mBucketNum); + mElements[it1.mBucketNum].order = 0; + mElements[it1.mBucketNum].pair = HashPairType(); + mUsed--; ++it1; } + // Rehash all of the non-empty buckets that follow the erased buckets. + IndexType bucketnum = it2.mBucketNum & mSizeMask; + while (!emptyBucket(bucketnum)) + { + const KT& key = mElements[bucketnum].pair.first; + unsigned int order = mElements[bucketnum].order; + mElements[bucketnum].order = 0; + + IndexType new_bucketnum = findBucket(key); + mElements[new_bucketnum].order = order; + + if (new_bucketnum != bucketnum) + { + mElements[new_bucketnum].pair = mElements[bucketnum].pair; + mElements[bucketnum].pair = HashPairType(); + } + + bucketnum = (bucketnum + 1) & mSizeMask; + } } private: @@ -507,7 +528,7 @@ class OHashTable inline IndexType findBucket(const KT& key) const { - IndexType bucketnum = (mHashFunc(key) * 2654435761u) & mSizeMask; + IndexType bucketnum = (mHashFunc(key) * 2654435761u) & mSizeMask; // [SL] NOTE: this can loop infinitely if there is no match and the table is full! while (!emptyBucket(bucketnum) && mElements[bucketnum].pair.first != key) @@ -560,7 +581,7 @@ class OHashTable if (new_bucketnum != bucketnum) { mElements[new_bucketnum].pair = mElements[bucketnum].pair; - mElements[bucketnum].pair = HashPairType(); + mElements[bucketnum].pair = HashPairType(); } bucketnum = (bucketnum + 1) & mSizeMask;