# 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;