java-topology/defects/xonotic-0002/patch/xonotic-0002.patch

54 lines
2 KiB
Diff

# UNDF: UNDF-2026-000000990
--- a/sv_main.c
+++ b/sv_main.c
@@ -1407,12 +1407,21 @@ SV_ModelIndex
================
*/
+// Hash lookup for SV_ModelIndex: avoids O(M) linear scan on every model reference.
+// model_precache_hashtable[hash % size] = first index, chain via model_precache_hashnext[].
+#define SV_PRECACHE_HASHSIZE 512
+static int sv_model_precache_hashtable[SV_PRECACHE_HASHSIZE];
+static int sv_model_precache_hashnext[MAX_MODELS];
+
+static unsigned SV_PrecacheHash(const char *s)
+{
+ unsigned hash = 0;
+ for (; *s; s++)
+ hash = hash * 31 + (unsigned char)*s;
+ return hash % SV_PRECACHE_HASHSIZE;
+}
+
int SV_ModelIndex(const char *s, int precachemode)
{
- int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE) ? 256 : MAX_MODELS);
+ int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE) ? 256 : MAX_MODELS);
char filename[MAX_QPATH];
if (!s || !*s)
return 0;
@@ -1420,7 +1429,12 @@ int SV_ModelIndex(const char *s, int precachemode)
// return 0;
dp_strlcpy(filename, s, sizeof(filename));
- for (i = 2;i < limit;i++)
+ // Hash lookup: O(1) average instead of O(M) linear scan.
+ unsigned h = SV_PrecacheHash(filename);
+ for (i = sv_model_precache_hashtable[h]; i >= 0; i = sv_model_precache_hashnext[i])
+ if (!strcmp(sv.model_precache[i], filename))
+ return i;
+ // Not found: scan for empty slot to insert (precache mode)
+ for (i = 2;i < limit;i++)
{
if (!sv.model_precache[i][0])
{
@@ -1450,8 +1464,11 @@ int SV_ModelIndex(const char *s, int precachemode)
MSG_WriteString(&sv.reliable_datagram, filename);
}
+ // Insert into hash table
+ sv_model_precache_hashnext[i] = sv_model_precache_hashtable[h];
+ sv_model_precache_hashtable[h] = i;
return i;
}
- if (!strcmp(sv.model_precache[i], filename))
- return i;
}
Con_Printf("SV_ModelIndex(\"%s\"): i (%i) == MAX_MODELS (%i)\n", filename, i, MAX_MODELS);