From 414440589e5475fb703447fef9770499e3099423 Mon Sep 17 00:00:00 2001
From: David Anderson <dvander@alliedmods.net>
Date: Sun, 25 Aug 2013 11:59:46 -0700
Subject: [PATCH] Switch PluginSys off KTrie (bug 5884 part 3, r=ds).

---
 core/logic/PluginSys.cpp  | 69 ++++++++++++++-------------------------
 core/logic/PluginSys.h    | 14 +++++---
 public/sm_namehashset.h   |  3 +-
 public/sm_stringhashmap.h | 11 +++++--
 4 files changed, 44 insertions(+), 53 deletions(-)

diff --git a/core/logic/PluginSys.cpp b/core/logic/PluginSys.cpp
index fd67f51a..36778713 100644
--- a/core/logic/PluginSys.cpp
+++ b/core/logic/PluginSys.cpp
@@ -1,5 +1,5 @@
 /**
- * vim: set ts=4 :
+ * vim: set ts=4 sw=4 tw=99 noet :
  * =============================================================================
  * SourceMod
  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
@@ -114,7 +114,7 @@ unsigned int CPlugin::CalcMemUsage()
 		sizeof(CPlugin) 
 		+ sizeof(IdentityToken_t)
 		+ (m_configs.size() * (sizeof(AutoConfig *) + sizeof(AutoConfig)))
-		+ m_pProps.mem_usage();
+		+ m_Props.mem_usage();
 
 	for (unsigned int i = 0; i < m_configs.size(); i++)
 	{
@@ -169,24 +169,22 @@ CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
 
 bool CPlugin::GetProperty(const char *prop, void **ptr, bool remove/* =false */)
 {
-	void **ptrpp = m_pProps.retrieve(prop);
-	bool exists = !!ptrpp;
+	StringHashMap<void *>::Result r = m_Props.find(prop);
+	if (!r.found())
+		return false;
 
-	if (exists)
-	{
-		if (ptr)
-			*ptr = *ptrpp;
-			
-		if (remove)
-			m_pProps.remove(prop);
-	}
+	if (ptr)
+		*ptr = r->value;
 
-	return exists;
+	if (remove)
+		m_Props.remove(r);
+
+	return true;
 }
 
 bool CPlugin::SetProperty(const char *prop, void *ptr)
 {
-	 return m_pProps.insert(prop, ptr);
+	 return m_Props.insert(prop, ptr);
 }
 
 IPluginRuntime *CPlugin::GetRuntime()
@@ -886,22 +884,19 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
 	libsys->CloseDirectory(dir);
 }
 
-LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength)
+LoadRes CPluginManager::_LoadPlugin(CPlugin **aResult, const char *path, bool debug, PluginType type, char error[], size_t maxlength)
 {
 	if (m_LoadingLocked)
-	{
 		return LoadRes_NeverLoad;
-	}
 
 	int err;
 
 	/**
 	 * Does this plugin already exist?
 	 */
-	CPlugin **pluginpp = m_LoadLookup.retrieve(path);
-	if (pluginpp && *pluginpp)
+	CPlugin *pPlugin;
+	if (m_LoadLookup.retrieve(path, &pPlugin))
 	{
-		CPlugin *pPlugin = *pluginpp;
 		/* Check to see if we should try reloading it */
 		if (pPlugin->GetStatus() == Plugin_BadLoad
 			|| pPlugin->GetStatus() == Plugin_Error
@@ -911,16 +906,13 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
 		}
 		else
 		{
-			if (_plugin)
-			{
-				*_plugin = pPlugin;
-			}
+			if (aResult)
+				*aResult = pPlugin;
 			return LoadRes_AlreadyLoaded;
 		}
 	}
 
-	CPlugin *pPlugin = CPlugin::CreatePlugin(path, error, maxlength);
-
+	pPlugin = CPlugin::CreatePlugin(path, error, maxlength);
 	assert(pPlugin != NULL);
 
 	pPlugin->m_type = PluginType_MapUpdated;
@@ -1034,10 +1026,8 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
 	time_t t = pPlugin->GetFileTimeStamp();
 	pPlugin->SetTimeStamp(t);
 
-	if (_plugin)
-	{
-		*_plugin = pPlugin;
-	}
+	if (aResult)
+		*aResult = pPlugin;
 
 	return (pPlugin->GetStatus() == Plugin_Loaded) ? LoadRes_Successful : loadFailure;
 }
@@ -2114,13 +2104,11 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
 				const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 				g_pSM->BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 
-				CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
-				if (!pluginpp || !*pluginpp)
+				if (!m_LoadLookup.retrieve(pluginfile, &pl))
 				{
 					rootmenu->ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 					return;
 				}
-				pl = *pluginpp;
 			}
 
 			char name[PLATFORM_MAX_PATH];
@@ -2206,13 +2194,11 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
 				const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 				g_pSM->BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 
-				CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
-				if (!pluginpp || !*pluginpp)
+				if (!m_LoadLookup.retrieve(pluginfile, &pl))
 				{
 					rootmenu->ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 					return;
 				}
-				pl = *pluginpp;
 			}
 
 			const sm_plugininfo_t *info = pl->GetPublicInfo();
@@ -2338,13 +2324,11 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
 				const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 				g_pSM->BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 
-				CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
-				if (!pluginpp || !*pluginpp)
+				if (!m_LoadLookup.retrieve(pluginfile, &pl))
 				{
 					rootmenu->ConsolePrint("[SM] Plugin %s is not loaded.", pluginfile);
 					return;
 				}
-				pl = *pluginpp;
 			}
 
 			char name[PLATFORM_MAX_PATH];
@@ -2604,13 +2588,8 @@ SMPlugin *CPluginManager::FindPluginByConsoleArg(const char *arg)
 		const char *ext = libsys->GetFileExtension(arg) ? "" : ".smx";
 		smcore.Format(pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
 
-		CPlugin **pluginpp = m_LoadLookup.retrieve(pluginfile);
-		if (!pluginpp)
-		{
+		if (!m_LoadLookup.retrieve(pluginfile, &pl))
 			return NULL;
-		}
-		
-		pl = *pluginpp;
 	}
 
 	return pl;
diff --git a/core/logic/PluginSys.h b/core/logic/PluginSys.h
index fecacf99..f231dacb 100644
--- a/core/logic/PluginSys.h
+++ b/core/logic/PluginSys.h
@@ -1,5 +1,5 @@
 /**
- * vim: set ts=4 :
+ * vim: set ts=4 sw=4 tw=99 noet :
  * =============================================================================
  * SourceMod
  * Copyright (C) 2004-2010 AlliedModders LLC.  All rights reserved.
@@ -43,8 +43,9 @@
 #include <sh_vector.h>
 #include <sh_string.h>
 #include "common_logic.h"
-#include <sm_trie_tpl.h>
 #include <IRootConsoleMenu.h>
+#include <sm_stringhashmap.h>
+#include <sm_namehashset.h>
 #include "ITranslator.h"
 #include "IGameConfigs.h"
 #include "NativeOwner.h"
@@ -160,6 +161,11 @@ public:
 	 * a valid (but error-stated) CPlugin will be returned.
 	 */
 	static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength);
+
+	static inline bool matches(const char *file, const CPlugin *plugin)
+	{
+		return strcmp(plugin->m_filename, file) == 0;
+	}
 public:
 
 	/**
@@ -254,7 +260,7 @@ private:
 	IPhraseCollection *m_pPhrases;
 	List<String> m_RequiredLibs;
 	List<String> m_Libraries;
-	KTrie<void *> m_pProps;
+	StringHashMap<void *> m_Props;
 	bool m_FakeNativesMissing;
 	bool m_LibraryMissing;
 	CVector<AutoConfig *> m_configs;
@@ -460,7 +466,7 @@ private:
 	List<IPluginsListener *> m_listeners;
 	List<CPlugin *> m_plugins;
 	CStack<CPluginManager::CPluginIterator *> m_iters;
-	KTrie<CPlugin *> m_LoadLookup;
+	NameHashSet<CPlugin *> m_LoadLookup;
 	bool m_AllPluginsLoaded;
 	IdentityToken_t *m_MyIdent;
 
diff --git a/public/sm_namehashset.h b/public/sm_namehashset.h
index dc1e347a..82c06912 100644
--- a/public/sm_namehashset.h
+++ b/public/sm_namehashset.h
@@ -61,7 +61,8 @@ class NameHashSet : public SystemAllocatorPolicy
 
 	// Default policy type: the two types are different. Use them directly.
 	template <typename KeyType, typename KeyPolicyType>
-	struct Policy {
+	struct Policy
+	{
 		typedef KeyType Payload;
 
 		static uint32_t hash(const CharsAndLength &key)
diff --git a/public/sm_stringhashmap.h b/public/sm_stringhashmap.h
index 5b254621..2ff68b3d 100644
--- a/public/sm_stringhashmap.h
+++ b/public/sm_stringhashmap.h
@@ -120,7 +120,7 @@ public:
 	bool retrieve(const char *aKey, T *aResult = NULL)
 	{
 		CharsAndLength key(aKey);
-		typename Internal::Result r = internal_.find(key);
+		Result r = internal_.find(key);
 		if (!r.found())
 			return false;
 		if (aResult)
@@ -137,7 +137,7 @@ public:
 	bool contains(const char *aKey)
 	{
 		CharsAndLength key(aKey);
-		typename Internal::Result r = internal_.find(key);
+		Result r = internal_.find(key);
 		return r.found();
 	}
 
@@ -173,7 +173,7 @@ public:
 	bool remove(const char *aKey)
 	{
 		CharsAndLength key(aKey);
-		typename Internal::Result r = internal_.find(key);
+		Result r = internal_.find(key);
 		if (!r.found())
 			return false;
 		memory_used_ -= key.length() + 1;
@@ -181,6 +181,11 @@ public:
 		return true;
 	}
 
+	void remove(Result &r)
+	{
+		internal_.remove(r);
+	}
+
 	void clear()
 	{
 		internal_.clear();