- Changed MakeKey's hash algorithm from a CRC32 to Paul Hsieh's SuperFastHash.

SVN r506 (trunk)
This commit is contained in:
Randy Heit 2007-03-24 14:59:28 +00:00
parent 490742cf46
commit 1f242fa79e
11 changed files with 311 additions and 92 deletions

View File

@ -1,3 +1,6 @@
March 24, 2007
- Changed MakeKey's hash algorithm from a CRC32 to Paul Hsieh's SuperFastHash.
March 20, 2007
- Moved the implementation for the Thing_Damage special into another function
so that I can create the ACS function Thing_Damage2. It's exactly the same as

View File

@ -3,7 +3,7 @@
** Functions for executing console commands and aliases
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** Copyright 1998-2007 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -32,6 +32,8 @@
**
*/
// HEADER FILES ------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -51,24 +53,9 @@
#include "m_crc32.h"
#include "v_text.h"
bool ParsingKeyConf;
// MACROS ------------------------------------------------------------------
static const char *KeyConfCommands[] =
{
"alias",
"defaultbind",
"addkeysection",
"addmenukey",
"addslotdefault",
"weaponsection",
"setslot",
"addplayerclass",
"clearplayerclasses"
};
static long ParseCommandLine (const char *args, int *argc, char **argv);
CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered?
// TYPES -------------------------------------------------------------------
class DWaitingCommand : public DThinker
{
@ -108,51 +95,78 @@ struct FActionMap
char Name[12];
};
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static long ParseCommandLine (const char *args, int *argc, char **argv);
static FConsoleCommand *FindNameInHashTable (FConsoleCommand **table, const char *name, size_t namelen);
static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *name, size_t namelen, FConsoleCommand **prev);
FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE];
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
// PUBLIC DATA DEFINITIONS -------------------------------------------------
CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered?
FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE];
FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack,
Button_Attack, Button_Speed, Button_MoveRight, Button_MoveLeft,
Button_Strafe, Button_LookDown, Button_LookUp, Button_Back,
Button_Forward, Button_Right, Button_Left, Button_MoveDown,
Button_MoveUp, Button_Jump, Button_ShowScores, Button_Crouch;
bool ParsingKeyConf;
// To add new actions, go to the console and type "key <action name>".
// This will give you the key value to use in the first column. Then
// insert your new action into this list so that the keys remain sorted
// in ascending order. No two keys can be identical. If yours matches
// an existing key, either modify MakeKey(), or (preferably) change the
// name of your action.
// an existing key, change the name of your action.
FActionMap ActionMaps[] =
{
{ 0x0f26fef6, &Button_Speed, "speed" },
{ 0x1ccf57bf, &Button_MoveUp, "moveup" },
{ 0x22beba5f, &Button_Klook, "klook" },
{ 0x47c02d3b, &Button_Attack, "attack" },
{ 0x6dcec137, &Button_Back, "back" },
{ 0x7a67e768, &Button_Left, "left" },
{ 0x8076f318, &Button_Crouch, "crouch" },
{ 0x84b8789a, &Button_MoveLeft, "moveleft" },
{ 0x8fd9bf1e, &Button_ShowScores, "showscores" },
{ 0x94b1cc4b, &Button_Use, "use" },
{ 0xa7b30616, &Button_Jump, "jump" },
{ 0xadfe4fff, &Button_Mlook, "mlook" },
{ 0xb4ca7514, &Button_Right, "right" },
{ 0xb563e265, &Button_LookDown, "lookdown" },
{ 0xb67a0835, &Button_Strafe, "strafe" },
{ 0xc4704c1d, &Button_AltAttack, "altattack" },
{ 0xe2200fc9, &Button_MoveDown, "movedown" },
{ 0xe78739bb, &Button_MoveRight, "moveright" },
{ 0xe7912f86, &Button_Forward, "forward" },
{ 0xf01cb105, &Button_LookUp, "lookup" },
{ 0x1eefa611, &Button_Jump, "jump" },
{ 0x201f1c55, &Button_Right, "right" },
{ 0x23a99cd7, &Button_Back, "back" },
{ 0x4463f43a, &Button_LookDown, "lookdown" },
{ 0x5622bf42, &Button_Attack, "attack" },
{ 0x57c25cb2, &Button_Klook, "klook" },
{ 0x59f3e907, &Button_Forward, "forward" },
{ 0x6167ce99, &Button_MoveDown, "movedown" },
{ 0x676885b8, &Button_AltAttack, "altattack" },
{ 0x6fa41b84, &Button_MoveLeft, "moveleft" },
{ 0x818f08e6, &Button_MoveRight, "moveright" },
{ 0xa2b62d8b, &Button_Mlook, "mlook" },
{ 0xab2c3e71, &Button_Crouch, "crouch" },
{ 0xb000b483, &Button_Left, "left" },
{ 0xb62b1e49, &Button_LookUp, "lookup" },
{ 0xb7e6a54b, &Button_Strafe, "strafe" },
{ 0xd5897c73, &Button_ShowScores, "showscores" },
{ 0xe0ccb317, &Button_Speed, "speed" },
{ 0xe0cfc260, &Button_Use, "use" },
{ 0xfdd701c7, &Button_MoveUp, "moveup" },
};
#define NUM_ACTIONS countof(ActionMaps)
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static const char *KeyConfCommands[] =
{
"alias",
"defaultbind",
"addkeysection",
"addmenukey",
"addslotdefault",
"weaponsection",
"setslot",
"addplayerclass",
"clearplayerclasses"
};
// CODE --------------------------------------------------------------------
IMPLEMENT_CLASS (DWaitingCommand)
@ -247,39 +261,141 @@ static int ListActionCommands (const char *pattern)
return count;
}
/* ======================================================================== */
/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative
license. See:
http://www.azillionmonkeys.com/qed/weblicense.html for license details.
http://www.azillionmonkeys.com/qed/hash.html */
#undef get16bits
#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
|| defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
#define get16bits(d) (*((const WORD *) (d)))
#endif
#if !defined (get16bits)
#define get16bits(d) ((((DWORD)(((const BYTE *)(d))[1])) << 8)\
+(DWORD)(((const BYTE *)(d))[0]) )
#endif
DWORD SuperFastHash (const char *data, size_t len)
{
DWORD hash = 0, tmp;
size_t rem;
if (len == 0 || data == NULL) return 0;
rem = len & 3;
len >>= 2;
/* Main loop */
for (;len > 0; len--)
{
hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2*sizeof (WORD);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem)
{
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= data[sizeof (WORD)] << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
/* A modified version to do a case-insensitive hash */
#undef get16bits
#define get16bits(d) ((((DWORD)tolower(((const BYTE *)(d))[1])) << 8)\
+(DWORD)tolower(((const BYTE *)(d))[0]) )
DWORD SuperFastHashI (const char *data, size_t len)
{
DWORD hash = 0, tmp;
size_t rem;
if (len <= 0 || data == NULL) return 0;
rem = len & 3;
len >>= 2;
/* Main loop */
for (;len > 0; len--)
{
hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2*sizeof (WORD);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem)
{
case 3: hash += get16bits (data);
hash ^= hash << 16;
hash ^= tolower(data[sizeof (WORD)]) << 18;
hash += hash >> 11;
break;
case 2: hash += get16bits (data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1: hash += tolower(*data);
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
/* ======================================================================== */
unsigned int MakeKey (const char *s)
{
if (s == NULL)
{
return 0xffffffff;
return 0;
}
DWORD key = 0xffffffff;
const DWORD *table = GetCRCTable ();
while (*s)
{
key = CRC1 (key, tolower (*s++), table);
}
return key ^ 0xffffffff;
return SuperFastHashI (s, strlen (s));
}
unsigned int MakeKey (const char *s, size_t len)
{
if (len == 0 || s == NULL)
{
return 0xffffffff;
}
DWORD key = 0xffffffff;
const DWORD *table = GetCRCTable ();
while (len > 0)
{
key = CRC1 (key, tolower(*s++), table);
--len;
}
return key ^ 0xffffffff;
return SuperFastHashI (s, len);
}
// FindButton scans through the actionbits[] array
@ -764,9 +880,6 @@ bool FConsoleCommand::AddToHash (FConsoleCommand **table)
unsigned int key;
FConsoleCommand *insert, **bucket;
if (!stricmp (m_Name, "toggle"))
key = 1;
key = MakeKey (m_Name);
bucket = &table[key % HASH_SIZE];

View File

@ -146,12 +146,6 @@ void PClass::InsertIntoHash ()
*hashpos = this;
}
// Find a type, passed the name as a string
const PClass *PClass::FindClass (const char *zaname)
{
return FindClass (FName (zaname, true));
}
// Find a type, passed the name as a name
const PClass *PClass::FindClass (FName zaname)
{

View File

@ -127,7 +127,10 @@ struct PClass
return ti->IsAncestorOf (this);
}
static const PClass *FindClass (const char *name);
// Find a type, given its name.
static const PClass *FindClass (const char *name) { return FindClass (FName (name, true)); }
static const PClass *FindClass (const FString &name) { return FindClass (FName (name, true)); }
static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); }
static const PClass *FindClass (FName name);
static TArray<PClass *> m_Types;

View File

@ -32,3 +32,28 @@
**
*/
// HEADER FILES ------------------------------------------------------------
// MACROS ------------------------------------------------------------------
// TYPES -------------------------------------------------------------------
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
// PUBLIC DATA DEFINITIONS -------------------------------------------------
// PRIVATE DATA DEFINITIONS ------------------------------------------------
// CODE --------------------------------------------------------------------
//==========================================================================
//
//
//
//==========================================================================

View File

@ -3,7 +3,7 @@
** Implements int-as-string mapping.
**
**---------------------------------------------------------------------------
** Copyright 2005-2006 Randy Heit
** Copyright 2005-2007 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -42,10 +42,10 @@
// The number of bytes to allocate to each NameBlock unless somebody is evil
// and wants a really long name. In that case, it gets its own NameBlock
// that is just large enough to hold it.
#define BLOCK_SIZE 1024
#define BLOCK_SIZE 4096
// How many entries to grow the NameArray by when it needs to grow.
#define NAME_GROW_AMOUNT 48
#define NAME_GROW_AMOUNT 256
// TYPES -------------------------------------------------------------------
@ -125,7 +125,7 @@ int FName::NameManager::FindName (const char *text, bool noCreate)
//==========================================================================
//
// The same as above, but the text length is also passed, for creating
// a name from a substring.
// a name from a substring or for speed if the length is already known.
//
//==========================================================================

View File

@ -2,7 +2,7 @@
** name.h
**
**---------------------------------------------------------------------------
** Copyright 2005-2006 Randy Heit
** Copyright 2005-2007 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -41,6 +41,8 @@ enum ENamedName
#undef xx
};
class FString;
class FName
{
public:
@ -48,6 +50,8 @@ public:
FName (const char *text) { Index = NameData.FindName (text, false); }
FName (const char *text, bool noCreate) { Index = NameData.FindName (text, noCreate); }
FName (const char *text, size_t textlen, bool noCreate) { Index = NameData.FindName (text, textlen, noCreate); }
FName (const FString &text);
FName (const FString &text, bool noCreate);
FName (const FName &other) { Index = other.Index; }
FName (ENamedName index) { Index = index; }
// ~FName () {} // Names can be added but never removed.
@ -58,6 +62,7 @@ public:
operator const char *() const { return NameData.NameArray[Index].Text; }
FName &operator = (const char *text) { Index = NameData.FindName (text, false); return *this; }
FName &operator = (const FString &text);
FName &operator = (const FName &other) { Index = other.Index; return *this; }
FName &operator = (ENamedName index) { Index = index; return *this; }
@ -98,7 +103,7 @@ protected:
// means this struct must only exist in the program's BSS section.
~NameManager();
enum { HASH_SIZE = 256 };
enum { HASH_SIZE = 1024 };
struct NameBlock;
NameBlock *Blocks;
@ -126,6 +131,7 @@ public:
FNameNoInit() : FName(NoInit) {}
FName &operator = (const char *text) { Index = NameData.FindName (text, false); return *this; }
FName &operator = (const FString &text);
FName &operator = (const FName &other) { Index = int(other); return *this; }
FName &operator = (ENamedName index) { Index = index; return *this; }
};

View File

@ -2,7 +2,7 @@
** version.h
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** Copyright 1998-2007 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -40,13 +40,13 @@
/** Lots of different version numbers **/
#define DOTVERSIONSTR_NOREV "2.1.7"
#define DOTVERSIONSTR_NOREV "2.1.8"
// The version string the user actually sees.
#define DOTVERSIONSTR DOTVERSIONSTR_NOREV " (r" SVN_REVISION_STRING ")"
// The version as seen in the Windows resource
#define RC_FILEVERSION 2,1,7,SVN_REVISION_NUMBER
#define RC_FILEVERSION 2,1,8,SVN_REVISION_NUMBER
#define RC_PRODUCTVERSION 2,1,0,0
#define RC_FILEVERSION2 DOTVERSIONSTR
#define RC_PRODUCTVERSION2 "2.1"
@ -73,8 +73,8 @@
// SAVEVER is the version of the information stored in level snapshots.
// Note that SAVEVER is not directly comparable to VERSION.
// SAVESIG should match SAVEVER.
#define SAVEVER 236
#define SAVESIG "ZDOOMSAVE236"
#define SAVEVER 237
#define SAVESIG "ZDOOMSAVE237"
// This is so that derivates can use the same savegame versions without worrying about engine compatibility
#define GAMESIG "ZDOOM"
@ -89,7 +89,7 @@
#endif
// MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 236 // Used by 2.1.7
#define MINSAVEVER 237 // Used by 2.1.8
// The maximum length of one save game description for the menus.
#define SAVESTRINGSIZE 24

View File

@ -35,7 +35,7 @@ END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"#include ""../version.h""\0"
"#include ""../version.h\0"
END
3 TEXTINCLUDE
@ -71,7 +71,7 @@ BEGIN
" VALUE ""FileDescription"", ""ZDoom""\r\n"
" VALUE ""FileVersion"", RC_FILEVERSION2\r\n"
" VALUE ""InternalName"", ""ZDoom""\r\n"
" VALUE ""LegalCopyright"", ""Copyright © 1993-1996, id Software & 1998-2006, Randy Heit""\r\n"
" VALUE ""LegalCopyright"", ""Copyright © 1993-1996 id Software, 1998-2007 Randy Heit""\r\n"
" VALUE ""LegalTrademarks"", ""Doom® is a Registered Trademark of id Software, Inc.""\r\n"
" VALUE ""OriginalFilename"", ""zdoom.exe""\r\n"
" VALUE ""ProductName"", ""ZDoom""\r\n"
@ -82,7 +82,7 @@ BEGIN
" BEGIN\r\n"
" VALUE ""Translation"", 0x409, 1200\r\n"
" END\r\n"
"END\r\0"
"END\0"
END
#endif // APSTUDIO_INVOKED
@ -497,7 +497,7 @@ BEGIN
VALUE "FileDescription", "ZDoom"
VALUE "FileVersion", RC_FILEVERSION2
VALUE "InternalName", "ZDoom"
VALUE "LegalCopyright", "Copyright © 1993-1996, id Software & 1998-2006, Randy Heit"
VALUE "LegalCopyright", "Copyright © 1993-1996 id Software, 1998-2007 Randy Heit"
VALUE "LegalTrademarks", "Doom® is a Registered Trademark of id Software, Inc."
VALUE "OriginalFilename", "zdoom.exe"
VALUE "ProductName", "ZDoom"

View File

@ -1,3 +1,37 @@
/*
** zstring.cpp
** A dynamically-allocated string class.
**
**---------------------------------------------------------------------------
** Copyright 2005-2007 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

View File

@ -1,3 +1,36 @@
/*
** zstring.h
**
**---------------------------------------------------------------------------
** Copyright 2005-2007 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#ifndef ZSTRING_H
#define ZSTRING_H
@ -257,4 +290,12 @@ namespace StringFormat
#undef PRINTFISH
// FName inline implementations that take FString parameters
inline FName::FName(const FString &text) { Index = NameData.FindName (text, text.Len(), false); }
inline FName::FName(const FString &text, bool noCreate) { Index = NameData.FindName (text, text.Len(), noCreate); }
inline FName &FName::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; }
inline FName &FNameNoInit::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; }
#endif