58 lines
1.7 KiB
Diff
58 lines
1.7 KiB
Diff
# UNDF: UNDF-2026-000000992
|
|
--- a/snd_main.c
|
|
+++ b/snd_main.c
|
|
@@ -888,6 +888,20 @@ S_FindName
|
|
==================
|
|
*/
|
|
+// Hash table for S_FindName: avoids O(N) linked list scan on every sound lookup.
|
|
+// The existing code has a TODO comment: "TODO: hash table search?"
|
|
+#define SFX_HASHSIZE 256
|
|
+static sfx_t *sfx_hashtable[SFX_HASHSIZE];
|
|
+
|
|
+static unsigned S_NameHash(const char *name)
|
|
+{
|
|
+ unsigned hash = 0;
|
|
+ const unsigned char *p;
|
|
+ for (p = (const unsigned char *)name; *p; p++)
|
|
+ hash = hash * 31 + *p;
|
|
+ return hash % SFX_HASHSIZE;
|
|
+}
|
|
+
|
|
sfx_t *S_FindName (const char *name)
|
|
{
|
|
sfx_t *sfx;
|
|
@@ -908,9 +922,12 @@ sfx_t *S_FindName (const char *name)
|
|
}
|
|
|
|
// Look for this sound in the list of known sfx
|
|
- // TODO: hash table search?
|
|
- for (sfx = known_sfx; sfx != NULL; sfx = sfx->next)
|
|
- if(!strcmp (sfx->name, name))
|
|
- return sfx;
|
|
+ // Hash table search replaces O(N) linked list scan.
|
|
+ unsigned hashkey = S_NameHash(name);
|
|
+ for (sfx = sfx_hashtable[hashkey]; sfx != NULL; sfx = sfx->hashnext)
|
|
+ if (!strcmp(sfx->name, name))
|
|
+ return sfx;
|
|
|
|
// check for # in the beginning, try lookup by soundindex
|
|
if (name[0] == '#' && name[1])
|
|
@@ -925,6 +942,9 @@ sfx_t *S_FindName (const char *name)
|
|
dp_strlcpy (sfx->name, name, sizeof (sfx->name));
|
|
sfx->memsize = sizeof(*sfx);
|
|
sfx->next = known_sfx;
|
|
+ // Insert into hash table
|
|
+ sfx->hashnext = sfx_hashtable[hashkey];
|
|
+ sfx_hashtable[hashkey] = sfx;
|
|
known_sfx = sfx;
|
|
|
|
return sfx;
|
|
--- a/snd_main.h
|
|
+++ b/snd_main.h
|
|
@@ -100,6 +100,7 @@ typedef struct sfx_s
|
|
unsigned int flags; // cf SFXFLAG_* defines
|
|
|
|
struct sfx_s *next;
|
|
+ struct sfx_s *hashnext; // hash chain for S_FindName O(1) lookup
|
|
unsigned int memsize; // total memory used (including sfx_t and fetcher data)
|
|
} sfx_t;
|