From 3bde52f79d1fa0241f0cd93afac84163f18d2779 Mon Sep 17 00:00:00 2001
From: John FrostFox <john.frostfox@gmail.com>
Date: Tue, 2 Nov 2021 13:49:39 +0300
Subject: [PATCH] A bit of fixes for hashtable routines

---
 src/Sourcefile    |  2 +-
 src/d_netcmd.c    |  6 +++---
 src/hashtable.c   | 33 +++++++++++++++------------------
 src/lua_script.c  |  9 ++-------
 src/p_savenetrb.c | 38 ++++++++++----------------------------
 5 files changed, 31 insertions(+), 57 deletions(-)

diff --git a/src/Sourcefile b/src/Sourcefile
index 75023900f..0dee91567 100755
--- a/src/Sourcefile
+++ b/src/Sourcefile
@@ -42,7 +42,6 @@ p_map.c
 p_maputl.c
 p_mobj.c
 p_polyobj.c
-hashtable.c
 p_saveg.c
 p_savenetrb.c
 p_setup.c
@@ -96,4 +95,5 @@ lua_taglib.c
 lua_polyobjlib.c
 lua_blockmaplib.c
 lua_hudlib.c
+hashtable.c
 
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 8d2df5a1a..b2c70375e 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -387,7 +387,7 @@ consvar_t cv_simmisstics = { "simmisstics", "Yes", 0, CV_YesNo, NULL, 0, NULL, N
 consvar_t cv_jittersmoothing = { "jittersmoothing", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL };
 
 static CV_PossibleValue_t simulateculldistance_cons_t[] = { {0, "MIN"}, {10000, "MAX"}, {0, NULL} };
-consvar_t cv_simulateculldistance = { "simcull", "2", 0, simulateculldistance_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
+consvar_t cv_simulateculldistance = { "simcull", "MIN", 0, simulateculldistance_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
 
 static CV_PossibleValue_t siminaccuracy_cons_t[] = { {1, "MIN"}, {10, "MAX"}, {0, NULL} };
 consvar_t cv_siminaccuracy = { "siminaccuracy", "MIN", 0, siminaccuracy_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
@@ -1050,9 +1050,9 @@ void D_RegisterClientCommands(void)
 	COM_AddCommand("skynum", Command_Skynum_f);
 	COM_AddCommand("weather", Command_Weather_f);
 	COM_AddCommand("toggletwod", Command_Toggletwod_f);
-// #ifdef _DEBUG
+#ifdef _DEBUG
 	COM_AddCommand("causecfail", Command_CauseCfail_f);
-// #endif
+#endif
 #ifdef LUA_ALLOW_BYTECODE
 	COM_AddCommand("dumplua", Command_Dumplua_f);
 #endif
diff --git a/src/hashtable.c b/src/hashtable.c
index 7b26ad499..cb086d384 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -20,8 +20,8 @@
 
 typedef struct mobjnum_linkedList_s{
     thinker_t* thinker;
-    struct mobjnum_linkedList_s* prev;
-    struct mobjnum_linkedList_s* next;
+    struct mobjnum_linkedList_s* prev; //the first element must always be null
+    struct mobjnum_linkedList_s* next; //the last element must always be null
 }
 mobjnum_linkedList;
 
@@ -29,7 +29,7 @@ mobjnum_linkedList mobjnum_Hashtable[HT_NUMLISTS]; //dumb and idiotic, there are
 //Wish I could just simply make a mobj_t array with UINT64_MAX entries, LOL
 
 void mobjnum_ht_linkedList_Wipe();
-/** Initializes simple mobjnum hashtable linked list.*/
+/** Initializes simple mobjnum/thinker hashtable linked list.*/
 void mobjnum_ht_linkedList_Init()
 {
     mobjnum_ht_linkedList_Wipe();
@@ -42,7 +42,7 @@ void mobjnum_ht_linkedList_Init()
     
 }
 
-/** Adds a mobj's address, determines in which list to add automatically
+/** Adds a thinker's address, determines in which list to add automatically
   *
   * \param mobj     Which mobj's memory address to add 
   */
@@ -80,18 +80,18 @@ void mobjnum_ht_linkedList_AddEntry (thinker_t* thinker)
             {
                 // CONS_Printf("next not exists, create\n");
                 currentEntry->next = malloc(sizeof(mobjnum_linkedList));
-                currentEntry->next->thinker = NULL;
+                currentEntry->next->thinker = thinker;
                 currentEntry->next->next = NULL;
                 currentEntry->next->prev = currentEntry;
+                next = NULL;
             }
             else
-                // CONS_Printf("next exists\n");
-            next = currentEntry->next;
+                next = currentEntry->next;
         }
     }
 }
 
-/** Removes a mobj's address by its mobjnum, determines from which list to remove automatically
+/** Removes a thinker's address by its mobjnum, determines from which list to remove automatically
   *
   * \param mobjnum     Which mobj's memory address to remove by itsmobjnum 
   */
@@ -107,10 +107,10 @@ void mobjnum_ht_linkedList_AddEntry (thinker_t* thinker)
 //     }
 // }
 
-/** Looks for a mobj by its mobjnum.
+/** Looks for a thinker by its mobjnum.
   *
   * \param mobjnumber mobj's mobjnum
-  * \return mobj_t* if an object is found, otherwise NULL.
+  * \return thinker_t* if an object is found, otherwise NULL. Cast it to mobj_t* to get the mobj.
   */
 thinker_t* mobjnum_ht_linkedList_Find (uint32_t mobjnumber)
 {
@@ -137,10 +137,10 @@ thinker_t* mobjnum_ht_linkedList_Find (uint32_t mobjnumber)
 
         if (((mobj_t *)currentEntry->thinker)->mobjnum == mobjnumber)
             return currentEntry->thinker;
-        else
-        {
+        if (currentEntry->next)
             next = currentEntry->next;
-        }
+        else
+            next = NULL;
     }
     return NULL;
 }
@@ -151,7 +151,7 @@ void mobjnum_ht_linkedList_Wipe()
     mobjnum_linkedList* currentEntry; // = &mobjnum_Hashtable[(UINT8)(mobj->mobjnum % HT_NUMLISTS)];
     mobjnum_linkedList* next;
 
-    for (uint8_t i = 0; i < HT_NUMLISTS; i++)
+    for (UINT8 i = 0; i < HT_NUMLISTS; i++)
     {
         if (!mobjnum_Hashtable[i].next)
             continue;
@@ -165,16 +165,13 @@ void mobjnum_ht_linkedList_Wipe()
             if (currentEntry->next)
             {
                 currentEntry->next = NULL;
-                // CONS_Printf("Has Next\n");
             }
             if (currentEntry->thinker)
             {
-                // CONS_Printf("Has mobj\n");
                 currentEntry->thinker = NULL;
             }
-            if (currentEntry->prev)
+            if (currentEntry->prev) //prevents freeing the first element
             {
-                // CONS_Printf("Has Prev\n");
                 currentEntry->prev = NULL;
                 free(currentEntry);
             }
diff --git a/src/lua_script.c b/src/lua_script.c
index d32c9c611..86adc36e5 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -36,7 +36,6 @@
 
 #include "doomstat.h"
 #include "g_state.h"
-
 #include "hashtable.h"
 
 lua_State *gL = NULL;
@@ -1662,14 +1661,9 @@ void LUA_UnArchive(void)
 	{
 		th = mobjnum_ht_linkedList_Find(mobjnum);
 		if (th && ((mobj_t *)th)->mobjnum == mobjnum)
-		{
-			// hashHits++;
 			UnArchiveExtVars(th);
-		}
 		else
 		{
-			// hashmiss++;
-			
 			for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
 			{
 				if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
@@ -1681,7 +1675,8 @@ void LUA_UnArchive(void)
 		}
 		mobjnum = READUINT32(save_p); // read a mobjnum
 	} 
-	
+
+	// "Optimized" old routine w/o hashtables
 	// mobjnum = READUINT32(save_p);
 	// while(mobjnum != UINT32_MAX) // repeat until end of mobjs marker.
 	// {
diff --git a/src/p_savenetrb.c b/src/p_savenetrb.c
index 34bd7bdf4..1a186da5f 100755
--- a/src/p_savenetrb.c
+++ b/src/p_savenetrb.c
@@ -41,6 +41,8 @@
 #include "console.h"
 #include "hashtable.h"
 
+
+
 // Block UINT32s to attempt to ensure that the correct data is
 // being preserved
 #define ARCHIVEBLOCK_MISC     0x7FEEDEED
@@ -66,6 +68,10 @@ typedef enum
 	DRONE      = 0x80,
 } player_saveflags;
 
+// Now save the pointers, tracer and target, but at load time we must
+// relink to this; the savegame contains the old position in the pointer
+// field copyed in the info field temporarily, but finally we just search
+// for the old position and relink to it.
 mobj_t *P_FindNewPosition_Hashtable(UINT32 oldposition)
 {
 	thinker_t *th;
@@ -81,6 +87,7 @@ mobj_t *P_FindNewPosition_Hashtable(UINT32 oldposition)
 		mobj = (mobj_t *)th;
 		if (mobj->mobjnum != oldposition)
 			continue;
+
 		return mobj;
 	}
 	CONS_Debug(DBG_GAMELOGIC, "mobj not found\n");
@@ -2850,30 +2857,6 @@ static void P_NetArchiveThinkers(void)
 	}
 }
 
-// Now save the pointers, tracer and target, but at load time we must
-// relink to this; the savegame contains the old position in the pointer
-// field copyed in the info field temporarily, but finally we just search
-// for the old position and relink to it.
-// mobj_t *P_FindNewPosition(UINT32 oldposition)
-// {
-// 	thinker_t *th;
-// 	mobj_t *mobj;
-
-// 	for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
-// 	{
-// 		if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
-// 			continue;
-
-// 		mobj = (mobj_t *)th;
-// 		if (mobj->mobjnum != oldposition)
-// 			continue;
-
-// 		return mobj;
-// 	}
-// 	CONS_Debug(DBG_GAMELOGIC, "mobj not found\n");
-// 	return NULL;
-// }
-
 static inline mobj_t *LoadMobj(UINT32 mobjnum)
 {
 	if (mobjnum == 0) return NULL;
@@ -4640,7 +4623,7 @@ static void P_LocalUnArchiveThinkers(boolean preserveLevel)
 			delay = (void *)currentthinker;
 			if (!(mobjnum = (UINT32)(size_t)delay->caller))
 				continue;
-			delay->caller = P_FindNewPosition(mobjnum);
+			delay->caller = P_FindNewPosition_Hashtable(mobjnum);
 		}
 	}
 	for (i = 0; i < sizeof(skyboxmo) / sizeof(skyboxmo[0]); i++)
@@ -5899,9 +5882,6 @@ boolean P_LoadGameState(const savestate_t* savestate)
     INT16 savedGameMap;
 	precise_t currentTime;
 	loadStateBenchmark = I_GetPreciseTime();
-
-	mobjnum_ht_linkedList_Init();
-
 	if (savestate->buffer == NULL)
 	{
 		loadStateBenchmark = I_GetPreciseTime() - loadStateBenchmark;
@@ -5920,6 +5900,8 @@ boolean P_LoadGameState(const savestate_t* savestate)
 		return false;
 	}
 
+	mobjnum_ht_linkedList_Init();
+
 	globalmobjnum = READUINT32(save_p);
 
 	con_muted = true;
-- 
GitLab