make lumpnumcache case sensitive + optimize + replace quickncase hash with FNV1a
lumpnumcache can be case sensitive W_CheckNumForName should also look for uppercase stuff and W_LumpExists is case sensitive anyways this avoids having to always account for case (toupper/tolower) during hash and string comparisons and even allows us to even directly compare our strings instead of using fastcmp (std::strings allow this!) from some benchmarking externally this makes this faster quite a bit
This commit is contained in:
parent
71175d82ca
commit
adce4197e0
14 changed files with 61 additions and 66 deletions
|
|
@ -866,7 +866,7 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
if (mapheaderinfo[num]->lumpname == NULL)
|
||||
{
|
||||
mapheaderinfo[num]->lumpname = Z_StrDup(name);
|
||||
mapheaderinfo[num]->lumpnamehash = quickncasehash(mapheaderinfo[num]->lumpname, MAXMAPLUMPNAME);
|
||||
mapheaderinfo[num]->lumpnamehash = FNV1a_QuickCaseHash(mapheaderinfo[num]->lumpname, MAXMAPLUMPNAME);
|
||||
}
|
||||
|
||||
do
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
cupheader_t *prev = NULL;
|
||||
UINT32 hash = quickncasehash(word2, MAXCUPNAME);
|
||||
UINT32 hash = FNV1a_QuickCaseHash(word2, MAXCUPNAME);
|
||||
|
||||
while (cup)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -412,22 +412,6 @@ extern boolean capslock;
|
|||
// i_system.c, replace getchar() once the keyboard has been appropriated
|
||||
INT32 I_GetKey(void);
|
||||
|
||||
/* http://www.cse.yorku.ca/~oz/hash.html */
|
||||
static inline
|
||||
UINT32 quickncasehash (const char *p, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
UINT32 x = 5381;
|
||||
|
||||
while (i < n && p[i])
|
||||
{
|
||||
x = (x * 33) ^ tolower(p[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
// Standard Hashing Functions (tm)
|
||||
// see W_MakeFileHash for hashing files
|
||||
#include "xxhash.h"
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ struct mapheader_t
|
|||
{
|
||||
// Core game information, not user-modifiable directly
|
||||
char *lumpname; ///< Lump name can be really long
|
||||
UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME)
|
||||
UINT32 lumpnamehash; ///< FNV1a_QuickCaseHash(->lumpname, MAXMAPLUMPNAME)
|
||||
lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap
|
||||
|
||||
void *thumbnailPic; ///< Lump data for the level select thumbnail.
|
||||
|
|
|
|||
|
|
@ -1028,7 +1028,7 @@ INT32 G_MapNumber(const char * name)
|
|||
#endif
|
||||
{
|
||||
INT32 map;
|
||||
UINT32 hash = quickncasehash(name, MAXMAPLUMPNAME);
|
||||
UINT32 hash = FNV1a_QuickCaseHash(name, MAXMAPLUMPNAME);
|
||||
|
||||
for (map = 0; map < nummapheaders; ++map)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomtype.h"
|
||||
#include "r_textures.h"
|
||||
#include "m_misc.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex)
|
|||
--------------------------------------------------*/
|
||||
static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName)
|
||||
{
|
||||
UINT32 checkHash = quickncasehash(checkName, 8);
|
||||
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, 8);
|
||||
size_t i;
|
||||
|
||||
if (maxBrightmapStorage == 0)
|
||||
|
|
@ -119,7 +120,7 @@ static boolean K_BRIGHTLumpParser(char *data, size_t size)
|
|||
{
|
||||
bms = K_NewBrightmap();
|
||||
strncpy(bms->textureName, tkn, 8);
|
||||
bms->textureHash = quickncasehash(tkn, 8);
|
||||
bms->textureHash = FNV1a_QuickCaseHash(tkn, 8);
|
||||
}
|
||||
|
||||
Z_Free(tkn);
|
||||
|
|
@ -129,7 +130,7 @@ static boolean K_BRIGHTLumpParser(char *data, size_t size)
|
|||
if (tkn && pos <= size)
|
||||
{
|
||||
strncpy(bms->brightmapName, tkn, 8);
|
||||
bms->brightmapHash = quickncasehash(tkn, 8);
|
||||
bms->brightmapHash = FNV1a_QuickCaseHash(tkn, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ void K_UserPropertyPush(mapUserProperties_t *user, const char *key, mapUserPrope
|
|||
memcpy(prop->key, key, keyLength + 1);
|
||||
prop->key[keyLength] = '\0';
|
||||
|
||||
prop->hash = quickncasehash(prop->key, keyLength);
|
||||
prop->hash = FNV1a_QuickCaseHash(prop->key, keyLength);
|
||||
|
||||
prop->type = type;
|
||||
switch (type)
|
||||
|
|
@ -101,7 +101,7 @@ void K_UserPropertyPush(mapUserProperties_t *user, const char *key, mapUserPrope
|
|||
mapUserProperty_t *K_UserPropertyFind(mapUserProperties_t *user, const char *key)
|
||||
{
|
||||
const size_t keyLength = strlen(key);
|
||||
const UINT32 hash = quickncasehash(key, keyLength);
|
||||
const UINT32 hash = FNV1a_QuickCaseHash(key, keyLength);
|
||||
size_t i;
|
||||
|
||||
if (user->length == 0)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "doomtype.h"
|
||||
#include "m_fixed.h"
|
||||
#include "m_random.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_local.h"
|
||||
#include "p_mobj.h"
|
||||
#include "r_textures.h"
|
||||
|
|
@ -98,7 +99,7 @@ t_splash_t *K_GetSplashByIndex(size_t checkIndex)
|
|||
--------------------------------------------------*/
|
||||
t_splash_t *K_GetSplashByName(const char *checkName)
|
||||
{
|
||||
UINT32 checkHash = quickncasehash(checkName, TERRAIN_NAME_LEN);
|
||||
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, TERRAIN_NAME_LEN);
|
||||
size_t i;
|
||||
|
||||
if (numSplashDefs == 0)
|
||||
|
|
@ -167,7 +168,7 @@ t_footstep_t *K_GetFootstepByIndex(size_t checkIndex)
|
|||
--------------------------------------------------*/
|
||||
t_footstep_t *K_GetFootstepByName(const char *checkName)
|
||||
{
|
||||
UINT32 checkHash = quickncasehash(checkName, TERRAIN_NAME_LEN);
|
||||
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, TERRAIN_NAME_LEN);
|
||||
size_t i;
|
||||
|
||||
if (numFootstepDefs == 0)
|
||||
|
|
@ -236,7 +237,7 @@ t_overlay_t *K_GetOverlayByIndex(size_t checkIndex)
|
|||
--------------------------------------------------*/
|
||||
t_overlay_t *K_GetOverlayByName(const char *checkName)
|
||||
{
|
||||
UINT32 checkHash = quickncasehash(checkName, TERRAIN_NAME_LEN);
|
||||
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, TERRAIN_NAME_LEN);
|
||||
size_t i;
|
||||
|
||||
if (numOverlayDefs == 0)
|
||||
|
|
@ -305,7 +306,7 @@ terrain_t *K_GetTerrainByIndex(size_t checkIndex)
|
|||
--------------------------------------------------*/
|
||||
terrain_t *K_GetTerrainByName(const char *checkName)
|
||||
{
|
||||
UINT32 checkHash = quickncasehash(checkName, TERRAIN_NAME_LEN);
|
||||
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, TERRAIN_NAME_LEN);
|
||||
size_t i;
|
||||
|
||||
if (numTerrainDefs > 0)
|
||||
|
|
@ -352,7 +353,7 @@ size_t K_GetDefaultTerrainID(void)
|
|||
--------------------------------------------------*/
|
||||
terrain_t *K_GetTerrainForTextureName(const char *checkName)
|
||||
{
|
||||
UINT32 checkHash = quickncasehash(checkName, 8);
|
||||
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, 8);
|
||||
size_t i;
|
||||
|
||||
if (numTerrainFloorDefs > 0)
|
||||
|
|
@ -380,7 +381,7 @@ terrain_t *K_GetTerrainForTextureName(const char *checkName)
|
|||
--------------------------------------------------*/
|
||||
size_t K_GetTerrainIDForTextureName(const char *checkName)
|
||||
{
|
||||
UINT32 checkHash = quickncasehash(checkName, 8);
|
||||
UINT32 checkHash = FNV1a_QuickCaseHash(checkName, 8);
|
||||
size_t i;
|
||||
|
||||
if (numTerrainFloorDefs > 0)
|
||||
|
|
@ -1933,7 +1934,7 @@ static boolean K_TERRAINLumpParser(char *data, size_t size)
|
|||
{
|
||||
t_splash_t *s = NULL;
|
||||
|
||||
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
|
||||
tknHash = FNV1a_QuickCaseHash(tkn, TERRAIN_NAME_LEN);
|
||||
|
||||
for (i = 0; i < numSplashDefs; i++)
|
||||
{
|
||||
|
|
@ -1974,7 +1975,7 @@ static boolean K_TERRAINLumpParser(char *data, size_t size)
|
|||
{
|
||||
t_footstep_t *fs = NULL;
|
||||
|
||||
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
|
||||
tknHash = FNV1a_QuickCaseHash(tkn, TERRAIN_NAME_LEN);
|
||||
|
||||
for (i = 0; i < numFootstepDefs; i++)
|
||||
{
|
||||
|
|
@ -2015,7 +2016,7 @@ static boolean K_TERRAINLumpParser(char *data, size_t size)
|
|||
{
|
||||
t_overlay_t *o = NULL;
|
||||
|
||||
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
|
||||
tknHash = FNV1a_QuickCaseHash(tkn, TERRAIN_NAME_LEN);
|
||||
|
||||
for (i = 0; i < numOverlayDefs; i++)
|
||||
{
|
||||
|
|
@ -2056,7 +2057,7 @@ static boolean K_TERRAINLumpParser(char *data, size_t size)
|
|||
{
|
||||
terrain_t *t = NULL;
|
||||
|
||||
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
|
||||
tknHash = FNV1a_QuickCaseHash(tkn, TERRAIN_NAME_LEN);
|
||||
|
||||
for (i = 0; i < numTerrainDefs; i++)
|
||||
{
|
||||
|
|
@ -2108,7 +2109,7 @@ static boolean K_TERRAINLumpParser(char *data, size_t size)
|
|||
{
|
||||
t_floor_t *f = NULL;
|
||||
|
||||
tknHash = quickncasehash(tkn, 8);
|
||||
tknHash = FNV1a_QuickCaseHash(tkn, 8);
|
||||
|
||||
for (i = 0; i < numTerrainFloorDefs; i++)
|
||||
{
|
||||
|
|
@ -2188,7 +2189,7 @@ static boolean K_TERRAINLumpParser(char *data, size_t size)
|
|||
{
|
||||
terrain_t *t = NULL;
|
||||
|
||||
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
|
||||
tknHash = FNV1a_QuickCaseHash(tkn, TERRAIN_NAME_LEN);
|
||||
|
||||
for (i = 0; i < numTerrainDefs; i++)
|
||||
{
|
||||
|
|
@ -2227,7 +2228,7 @@ static boolean K_TERRAINLumpParser(char *data, size_t size)
|
|||
{
|
||||
t_footstep_t *fs = NULL;
|
||||
|
||||
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
|
||||
tknHash = FNV1a_QuickCaseHash(tkn, TERRAIN_NAME_LEN);
|
||||
|
||||
for (i = 0; i < numFootstepDefs; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2537,3 +2537,22 @@ const char * M_Ftrim (double f)
|
|||
return &dig[1];/* skip the 0 */
|
||||
}
|
||||
}
|
||||
|
||||
#define FNV1A_OFFSET_BASIS 0x811C9DC5
|
||||
#define FNV1A_PRIME 0x01000193
|
||||
|
||||
// Behaves like the old quickncasehash
|
||||
// Stops either if it encounters null terminator
|
||||
// or reaches size
|
||||
UINT32 FNV1a_QuickCaseHash(const char *message, size_t size)
|
||||
{
|
||||
UINT32 hash = FNV1A_OFFSET_BASIS;
|
||||
|
||||
for (size_t i = 0; i < size && message[i]; i++)
|
||||
{
|
||||
hash ^= tolower(message[i]);
|
||||
hash *= FNV1A_PRIME;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ const char * M_Ftrim (double);
|
|||
// counting bits, for weapon ammo code, usually
|
||||
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
|
||||
|
||||
// Hashes some message using FNV-1a
|
||||
UINT32 FNV1a_QuickCaseHash(const char *message, size_t size);
|
||||
|
||||
#include "w_wad.h"
|
||||
extern char configfile[MAX_WADPATH];
|
||||
|
||||
|
|
|
|||
|
|
@ -1160,7 +1160,7 @@ Rloadflats (INT32 i, INT32 w)
|
|||
|
||||
// Set texture properties.
|
||||
memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
texture->hash = FNV1a_QuickCaseHash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
|
||||
|
|
@ -1261,7 +1261,7 @@ Rloadtextures (INT32 i, INT32 w)
|
|||
|
||||
// Set texture properties.
|
||||
memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
texture->hash = quickncasehash(texture->name, 8);
|
||||
texture->hash = FNV1a_QuickCaseHash(texture->name, 8);
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength))
|
||||
|
|
@ -1800,7 +1800,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture)
|
|||
// Allocate memory for a zero-patch texture. Obviously, we'll be adding patches momentarily.
|
||||
resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t),PU_STATIC,NULL);
|
||||
memcpy(resultTexture->name, newTextureName, 8);
|
||||
resultTexture->hash = quickncasehash(newTextureName, 8);
|
||||
resultTexture->hash = FNV1a_QuickCaseHash(newTextureName, 8);
|
||||
resultTexture->width = newTextureWidth;
|
||||
resultTexture->height = newTextureHeight;
|
||||
resultTexture->type = TEXTURETYPE_TEXTURE;
|
||||
|
|
@ -2014,7 +2014,7 @@ INT32 R_CheckTextureNumForName(const char *name, UINT8 type)
|
|||
|
||||
PaletteTextureHack(&name);
|
||||
|
||||
hash = quickncasehash(name, 8);
|
||||
hash = FNV1a_QuickCaseHash(name, 8);
|
||||
|
||||
for (i = 0; i < tidcachelen; i++)
|
||||
if (tidcache[i].type == type && tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8))
|
||||
|
|
|
|||
|
|
@ -1373,7 +1373,7 @@ musicdef_t *S_FindMusicDef(const char *name, UINT8 *i)
|
|||
if (!name || !name[0])
|
||||
return NULL;
|
||||
|
||||
hash = quickncasehash (name, 6);
|
||||
hash = FNV1a_QuickCaseHash (name, 6);
|
||||
|
||||
for (def = musicdefstart; def; def = def->next)
|
||||
{
|
||||
|
|
@ -1454,7 +1454,7 @@ ReadMusicDefFields
|
|||
break;
|
||||
STRBUFCPY(def->name[i], value);
|
||||
strlwr(def->name[i]);
|
||||
def->hash[i] = quickncasehash (def->name[i], 6);
|
||||
def->hash[i] = FNV1a_QuickCaseHash (def->name[i], 6);
|
||||
i++;
|
||||
} while ((value = strtok(NULL," ,")) != NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -107,8 +107,8 @@ struct LumpnumStringEquals
|
|||
{
|
||||
bool operator()(const std::string& str1, const std::string& str2) const
|
||||
{
|
||||
// fasticmp should be plenty fast and ignores case
|
||||
return fasticmp(str1.c_str(), str2.c_str());
|
||||
//return fastcmp(str1.c_str(), str2.c_str());
|
||||
return str1 == str2;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -455,12 +455,12 @@ boolean W_MakeFileHash(const char *filename, boolean openwad, UINT64 *ret)
|
|||
}
|
||||
|
||||
// Invalidates the cache of lump numbers. Call this whenever a wad is added.
|
||||
static void W_InvalidateLumpnumCache(void)
|
||||
FUNCINLINE static ATTRINLINE void W_InvalidateLumpnumCache(void)
|
||||
{
|
||||
lumpnumcache.clear();
|
||||
}
|
||||
|
||||
UINT32 W_HashLumpName(const char *name, size_t len)
|
||||
FUNCINLINE static ATTRINLINE UINT32 W_HashLumpName(const char *name, size_t len)
|
||||
{
|
||||
char uname[len + 1];
|
||||
strlcpy(uname, name, len + 1);
|
||||
|
|
@ -1456,7 +1456,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
return INT16_MAX;
|
||||
}
|
||||
|
||||
static lumpnum_t CheckLumpInCache(const char *name)
|
||||
FUNCINLINE static ATTRINLINE lumpnum_t CheckLumpInCache(const char *name)
|
||||
{
|
||||
auto it = lumpnumcache.find(name);
|
||||
if (it != lumpnumcache.end())
|
||||
|
|
@ -1465,9 +1465,9 @@ static lumpnum_t CheckLumpInCache(const char *name)
|
|||
return LUMPERROR;
|
||||
}
|
||||
|
||||
static void AddLumpToCache(lumpnum_t lumpnum, const char *name)
|
||||
FUNCINLINE static ATTRINLINE void AddLumpToCache(lumpnum_t lumpnum, const char *name)
|
||||
{
|
||||
lumpnumcache.insert({name, lumpnum});
|
||||
lumpnumcache.emplace(name, lumpnum);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1709,21 +1709,10 @@ UINT8 W_LumpExists(const char *name)
|
|||
UINT32 hash;
|
||||
size_t namelen;
|
||||
|
||||
// Check the lumpnumcache first.
|
||||
lumpnum_t cachenum = CheckLumpInCache(name);
|
||||
if (cachenum != LUMPERROR)
|
||||
{
|
||||
// ok ok, we did find a lump in our lumpcache BUTT
|
||||
// the lumpcache map is case insensitive
|
||||
// extract the lumpinfo out of the lumpnum
|
||||
// so we can do one more extra case ~sensitive~ name compare
|
||||
// otherwise we gotta fall through to our manual lump search below
|
||||
// lumpnum == (i << 16) | check
|
||||
UINT16 wadnum = (cachenum >> 16) & 0xFFFF;
|
||||
UINT16 lumpid = cachenum & 0xFFFF;
|
||||
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[lumpid];
|
||||
if (fastcmp(lump_p->longname, name))
|
||||
return true;
|
||||
}
|
||||
return cachenum;
|
||||
|
||||
namelen = strlen(name);
|
||||
hash = W_HashLumpName(name, namelen);
|
||||
|
|
|
|||
|
|
@ -166,8 +166,6 @@ boolean W_MakeFileHash(const char *filename, boolean openwad, UINT64 *ret);
|
|||
// W_InitMultipleFiles exits if a file was not found, but not if all is okay.
|
||||
INT32 W_InitMultipleFiles(char **filenames, boolean addons);
|
||||
|
||||
UINT32 W_HashLumpName(const char *name, size_t len);
|
||||
|
||||
const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
|
||||
const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue