diff --git a/public/amtl/am-hashmap.h b/public/amtl/am-hashmap.h
index 632d9fae..c4653096 100644
--- a/public/amtl/am-hashmap.h
+++ b/public/amtl/am-hashmap.h
@@ -131,6 +131,10 @@ class HashMap : public AllocPolicy
return table_.add(i);
}
+ void clear() {
+ table_.clear();
+ }
+
size_t estimateMemoryUse() const {
return table_.estimateMemoryUse();
}
diff --git a/public/amtl/am-hashtable.h b/public/amtl/am-hashtable.h
index 7e04a0b6..8e4660a5 100644
--- a/public/amtl/am-hashtable.h
+++ b/public/amtl/am-hashtable.h
@@ -60,6 +60,10 @@ namespace detail {
destruct();
hash_ = kRemovedHash;
}
+ void setFree() {
+ destruct();
+ hash_ = kFreeHash;
+ }
void initialize() {
hash_ = kFreeHash;
}
@@ -432,6 +436,14 @@ class HashTable : public AllocPolicy
return true;
}
+ void clear() {
+ for (size_t i = 0; i < capacity_; i++) {
+ table_[i].setFree();
+ }
+ ndeleted_ = 0;
+ nelements_ = 0;
+ }
+
size_t estimateMemoryUse() const {
return sizeof(Entry) * capacity_;
}
diff --git a/public/sm_stringhashmap.h b/public/sm_stringhashmap.h
new file mode 100644
index 00000000..5d7d7d0b
--- /dev/null
+++ b/public/sm_stringhashmap.h
@@ -0,0 +1,178 @@
+/**
+ * vim: set ts=4 sw=4 tw=99 noet :
+ * =============================================================================
+ * SourceMod
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#ifndef _include_sourcemod_hashtable_h_
+#define _include_sourcemod_hashtable_h_
+
+#include
+#include
+#include
+#include
+
+namespace SourceMod
+{
+
+using namespace ke;
+
+namespace detail
+{
+ class CharsAndLength
+ {
+ public:
+ CharsAndLength(const char *str)
+ : str_(str),
+ length_(0)
+ {
+ int c;
+ uint32_t hash = 0;
+ while ((c = *str++))
+ hash = c + (hash << 6) + (hash << 16) - hash;
+ hash_ = hash;
+ length_ = str - str_ - 1;
+ }
+
+ uint32_t hash() const {
+ return hash_;
+ }
+ const char *chars() const {
+ return str_;
+ }
+ size_t length() const {
+ return length_;
+ }
+
+ private:
+ const char *str_;
+ size_t length_;
+ uint32_t hash_;
+ };
+
+ struct StringHashMapPolicy
+ {
+ static inline bool matches(const CharsAndLength &lookup, const AString &key) {
+ return lookup.length() == key.length() &&
+ memcmp(lookup.chars(), key.chars(), key.length()) == 0;
+ }
+ static inline uint32_t hash(const CharsAndLength &key) {
+ return key.hash();
+ }
+ };
+}
+
+template
+class StringHashMap
+{
+ typedef detail::CharsAndLength CharsAndLength;
+ typedef HashMap Internal;
+
+public:
+ StringHashMap()
+ : internal_(SystemAllocatorPolicy()),
+ memory_used_(0)
+ {
+ if (!internal_.init())
+ internal_.reportOutOfMemory();
+ }
+
+ // Some KTrie-like helper functions.
+ bool retrieve(const char *aKey, T *aResult = NULL)
+ {
+ CharsAndLength key(aKey);
+ typename Internal::Result r = internal_.find(key);
+ if (!r.found())
+ return false;
+ if (aResult)
+ *aResult = r->value;
+ return true;
+ }
+
+ bool contains(const char *aKey)
+ {
+ CharsAndLength key(aKey);
+ typename Internal::Result r = internal_.find(key);
+ return r.found();
+ }
+
+ bool replace(const char *aKey, const T &value)
+ {
+ CharsAndLength key(aKey);
+ typename Internal::Insert i = internal_.findForAdd(key);
+ if (!i.found())
+ {
+ memory_used_ += key.length() + 1;
+ return internal_.add(i, value);
+ }
+ i->value = value;
+ return true;
+ }
+
+ bool insert(const char *aKey, const T &value)
+ {
+ CharsAndLength key(aKey);
+ typename Internal::Insert i = internal_.findForAdd(key);
+ if (i.found())
+ return false;
+ if (!internal_.add(i))
+ return false;
+ memory_used_ += key.length() + 1;
+ i->key = aKey;
+ i->value = value;
+ return true;
+ }
+
+ bool remove(const char *aKey)
+ {
+ CharsAndLength key(aKey);
+ typename Internal::Result r = internal_.find(key);
+ if (!r.found())
+ return false;
+ memory_used_ -= key.length() + 1;
+ internal_.remove(r);
+ return true;
+ }
+
+ void clear()
+ {
+ internal_.clear();
+ }
+
+ size_t mem_usage() const {
+ return internal_.estimateMemoryUse() + memory_used_;
+ }
+
+private:
+ Internal internal_;
+ size_t memory_used_;
+};
+
+}
+
+#endif // _include_sourcemod_hashtable_h_
diff --git a/public/sm_trie_tpl.h b/public/sm_trie_tpl.h
index d0576929..2d6ed9b9 100644
--- a/public/sm_trie_tpl.h
+++ b/public/sm_trie_tpl.h
@@ -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.
@@ -45,11 +45,15 @@ enum NodeType
};
/**
- * @brief Trie class for storing key/value pairs, based on double array tries.
- * @file sm_trie_tpl.h
+ * @brief DEPRECATED. This class scales extremely poorly; insertion scales
+ * quadratic (O(n^2)) with respect to the number of elements in the table.
+ * Only use this class if you have less than 200 elements or so. Otherwise,
+ * use StringHashMap in sm_hashtable.h which scales linearly and has comparable
+ * retrievable performance.
*
- * For full works cited and implementation overview, there is a big comment
- * block at the bottom of this file.
+ * See bug 5878 for more detail.
+ *
+ * @file sm_trie_tpl.h
*/
template