Switch GameConfigs to hash tables (bug 5878 part 3, r=ds).

This commit is contained in:
David Anderson 2013-08-25 01:42:16 -07:00
parent 04bb2d1066
commit d14b5fe00b
4 changed files with 49 additions and 47 deletions

View File

@ -119,7 +119,6 @@ static bool DoesEngineMatch(const char *value)
CGameConfig::CGameConfig(const char *file, const char *engine) CGameConfig::CGameConfig(const char *file, const char *engine)
{ {
strncopy(m_File, file, sizeof(m_File)); strncopy(m_File, file, sizeof(m_File));
m_pAddresses = new KTrie<AddressConf>();
m_pStrings = new BaseStringTable(512); m_pStrings = new BaseStringTable(512);
m_CustomLevel = 0; m_CustomLevel = 0;
@ -212,13 +211,10 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
} }
else else
{ {
ITextListener_SMC **pListen = g_GameConfigs.m_customHandlers.retrieve(name); if (g_GameConfigs.m_customHandlers.retrieve(name, &m_CustomHandler))
if (pListen != NULL)
{ {
m_CustomLevel = 0; m_CustomLevel = 0;
m_ParseState = PSTATE_GAMEDEFS_CUSTOM; m_ParseState = PSTATE_GAMEDEFS_CUSTOM;
m_CustomHandler = *pListen;
m_CustomHandler->ReadSMC_ParseStart(); m_CustomHandler->ReadSMC_ParseStart();
break; break;
} }
@ -617,7 +613,7 @@ skip_find:
} }
AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead); AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead);
m_pAddresses->replace(m_Address, addrConf); m_Addresses.replace(m_Address, addrConf);
break; break;
} }
@ -765,7 +761,7 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
m_Offsets.clear(); m_Offsets.clear();
m_Props.clear(); m_Props.clear();
m_Keys.clear(); m_Keys.clear();
m_pAddresses->clear(); m_Addresses.clear();
char path[PLATFORM_MAX_PATH]; char path[PLATFORM_MAX_PATH];
@ -920,20 +916,15 @@ void CGameConfig::SetParseEngine(const char *engine)
bool CGameConfig::GetOffset(const char *key, int *value) bool CGameConfig::GetOffset(const char *key, int *value)
{ {
int *pvalue; return m_Offsets.retrieve(key, value);
if ((pvalue = m_Offsets.retrieve(key)) == NULL)
return false;
*value = *pvalue;
return true;
} }
const char *CGameConfig::GetKeyValue(const char *key) const char *CGameConfig::GetKeyValue(const char *key)
{ {
int *pkey; int address;
if ((pkey = m_Keys.retrieve(key)) == NULL) if (!m_Keys.retrieve(key, &address))
return NULL; return NULL;
return m_pStrings->GetString(*pkey); return m_pStrings->GetString(address);
} }
//memory addresses below 0x10000 are automatically considered invalid for dereferencing //memory addresses below 0x10000 are automatically considered invalid for dereferencing
@ -941,25 +932,25 @@ const char *CGameConfig::GetKeyValue(const char *key)
bool CGameConfig::GetAddress(const char *key, void **retaddr) bool CGameConfig::GetAddress(const char *key, void **retaddr)
{ {
AddressConf *addrConf; StringHashMap<AddressConf>::Result r = m_Addresses.find(key);
if (!r.found())
addrConf = m_pAddresses->retrieve(key);
if (!addrConf)
{ {
*retaddr = NULL; *retaddr = NULL;
return false; return false;
} }
AddressConf &addrConf = r->value;
void *addr; void *addr;
if (!GetMemSig(addrConf->signatureName, &addr)) if (!GetMemSig(addrConf.signatureName, &addr))
{ {
*retaddr = NULL; *retaddr = NULL;
return false; return false;
} }
for (int i = 0; i < addrConf->readCount; ++i) for (int i = 0; i < addrConf.readCount; ++i)
{ {
int offset = addrConf->read[i]; int offset = addrConf.read[i];
//NULLs in the middle of an indirection chain are bad, end NULL is ok //NULLs in the middle of an indirection chain are bad, end NULL is ok
if (addr == NULL || reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS) if (addr == NULL || reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
@ -1000,11 +991,7 @@ SendProp *CGameConfig::GetSendProp(const char *key)
bool CGameConfig::GetMemSig(const char *key, void **addr) bool CGameConfig::GetMemSig(const char *key, void **addr)
{ {
void **paddr; return m_Sigs.retrieve(key, addr);
if ((paddr = m_Sigs.retrieve(key)) == NULL)
return false;
*addr = *paddr;
return true;
} }
GameConfigManager::GameConfigManager() GameConfigManager::GameConfigManager()
@ -1074,7 +1061,6 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon
retval = pConfig->Reparse(error, maxlength); retval = pConfig->Reparse(error, maxlength);
} }
m_cfgs.push_back(pConfig);
m_Lookup.insert(file, pConfig); m_Lookup.insert(file, pConfig);
*_pConfig = pConfig; *_pConfig = pConfig;
@ -1108,22 +1094,16 @@ void GameConfigManager::AddUserConfigHook(const char *sectionname, ITextListener
m_customHandlers.insert(sectionname, listener); m_customHandlers.insert(sectionname, listener);
} }
void GameConfigManager::RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener) void GameConfigManager::RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *aListener)
{ {
ITextListener_SMC **pListener = m_customHandlers.retrieve(sectionname); ITextListener_SMC *listener;
if (!m_customHandlers.retrieve(sectionname, &listener))
if (pListener == NULL)
{
return; return;
}
if (*pListener != listener) if (listener != aListener)
{
return; return;
}
m_customHandlers.remove(sectionname); m_customHandlers.remove(sectionname);
return; return;
} }

View File

@ -35,10 +35,10 @@
#include "common_logic.h" #include "common_logic.h"
#include <IGameConfigs.h> #include <IGameConfigs.h>
#include <ITextParsers.h> #include <ITextParsers.h>
#include <sh_list.h>
#include "sm_memtable.h" #include "sm_memtable.h"
#include <sm_trie_tpl.h> #include <sm_trie_tpl.h>
#include <am-refcounting.h> #include <am-refcounting.h>
#include <sm_stringhashmap.h>
using namespace SourceMod; using namespace SourceMod;
using namespace SourceHook; using namespace SourceHook;
@ -73,10 +73,10 @@ private:
ke::AutoPtr<BaseStringTable> m_pStrings; ke::AutoPtr<BaseStringTable> m_pStrings;
char m_File[PLATFORM_MAX_PATH]; char m_File[PLATFORM_MAX_PATH];
char m_CurFile[PLATFORM_MAX_PATH]; char m_CurFile[PLATFORM_MAX_PATH];
KTrie<int> m_Offsets; StringHashMap<int> m_Offsets;
KTrie<SendProp *> m_Props; KTrie<SendProp *> m_Props;
KTrie<int> m_Keys; StringHashMap<int> m_Keys;
KTrie<void *> m_Sigs; StringHashMap<void *> m_Sigs;
/* Parse states */ /* Parse states */
int m_ParseState; int m_ParseState;
unsigned int m_IgnoreLevel; unsigned int m_IgnoreLevel;
@ -110,7 +110,7 @@ private:
char m_AddressSignature[64]; char m_AddressSignature[64];
int m_AddressReadCount; int m_AddressReadCount;
int m_AddressRead[8]; int m_AddressRead[8];
ke::AutoPtr<KTrie<AddressConf> > m_pAddresses; StringHashMap<AddressConf> m_Addresses;
const char *m_pEngine; const char *m_pEngine;
const char *m_pBaseEngine; const char *m_pBaseEngine;
}; };
@ -139,10 +139,9 @@ public: //SMGlobalClass
public: public:
void RemoveCachedConfig(CGameConfig *config); void RemoveCachedConfig(CGameConfig *config);
private: private:
List<CGameConfig *> m_cfgs;
KTrie<CGameConfig *> m_Lookup; KTrie<CGameConfig *> m_Lookup;
public: public:
KTrie<ITextListener_SMC *> m_customHandlers; StringHashMap<ITextListener_SMC *> m_customHandlers;
}; };
extern GameConfigManager g_GameConfigs; extern GameConfigManager g_GameConfigs;

View File

@ -33,6 +33,7 @@
#include <new> #include <new>
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include "am-allocator-policies.h"
#include "am-utility.h" #include "am-utility.h"
namespace ke { namespace ke {

View File

@ -32,6 +32,18 @@
#ifndef _include_sourcemod_hashtable_h_ #ifndef _include_sourcemod_hashtable_h_
#define _include_sourcemod_hashtable_h_ #define _include_sourcemod_hashtable_h_
/**
* @file sm_stringhashmap.h
*
* @brief Generic Key -> Value map class, based on a hash table. The Key, in
* this case, is always an ASCII string, and the value type is a template
* parameter. This class is intended as a drop-in replacement for KTrie
* (though the retrieve() signature has been improved).
*
* If your Value type already contains the key string, consider using
* NameHashSet instead.
*/
#include <am-allocator-policies.h> #include <am-allocator-policies.h>
#include <am-hashmap.h> #include <am-hashmap.h>
#include <am-string.h> #include <am-string.h>
@ -102,6 +114,8 @@ public:
internal_.reportOutOfMemory(); internal_.reportOutOfMemory();
} }
typedef typename Internal::Result Result;
// Some KTrie-like helper functions. // Some KTrie-like helper functions.
bool retrieve(const char *aKey, T *aResult = NULL) bool retrieve(const char *aKey, T *aResult = NULL)
{ {
@ -114,6 +128,12 @@ public:
return true; return true;
} }
Result find(const char *aKey)
{
CharsAndLength key(aKey);
return internal_.find(key);
}
bool contains(const char *aKey) bool contains(const char *aKey)
{ {
CharsAndLength key(aKey); CharsAndLength key(aKey);
@ -128,7 +148,9 @@ public:
if (!i.found()) if (!i.found())
{ {
memory_used_ += key.length() + 1; memory_used_ += key.length() + 1;
return internal_.add(i, value); if (!internal_.add(i, value))
return false;
i->key = aKey;
} }
i->value = value; i->value = value;
return true; return true;