diff --git a/core/smn_adt_trie.cpp b/core/smn_adt_trie.cpp index 79fc6585..2aab9833 100644 --- a/core/smn_adt_trie.cpp +++ b/core/smn_adt_trie.cpp @@ -498,6 +498,24 @@ static cell_t GetTrieString(IPluginContext *pContext, const cell_t *params) return 1; } +static cell_t GetTrieSize(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl; + CellTrie *pTrie; + HandleError err; + HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent); + + hndl = params[1]; + + if ((err = g_HandleSys.ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err); + } + + return pTrie->trie.size(); +} + REGISTER_NATIVES(trieNatives) { {"ClearTrie", ClearTrie}, @@ -509,5 +527,6 @@ REGISTER_NATIVES(trieNatives) {"SetTrieArray", SetTrieArray}, {"SetTrieString", SetTrieString}, {"SetTrieValue", SetTrieValue}, + {"GetTrieSize", GetTrieSize}, {NULL, NULL}, }; diff --git a/plugins/include/adt_trie.inc b/plugins/include/adt_trie.inc index 303b1949..b777d41d 100644 --- a/plugins/include/adt_trie.inc +++ b/plugins/include/adt_trie.inc @@ -144,3 +144,15 @@ native RemoveFromTrie(Handle:trie, const String:key[]); * @error Invalid Handle. */ native ClearTrie(Handle:trie); + +/** + * Retrieves the number of elements in a trie. + * + * Note that trie items are not enumerable/iteratable. If you need to + * retrieve the elements in a trie, store its keys in an ADT Array. + * + * @param trie Trie Handle. + * @return Number of elements in the trie. + * @error Invalid Handle. + */ +native GetTrieSize(Handle:trie); diff --git a/public/sm_trie_tpl.h b/public/sm_trie_tpl.h index 5d9b0b59..5018c8a2 100644 --- a/public/sm_trie_tpl.h +++ b/public/sm_trie_tpl.h @@ -83,6 +83,8 @@ public: node->value.~K(); node->valset = false; + m_numElements--; + return true; } @@ -164,6 +166,8 @@ public: m_empty->valset = true; new (&m_empty->value) K(obj); + m_numElements++; + return true; } @@ -204,6 +208,8 @@ public: node->valset = true; new (&node->value) K(obj); + m_numElements++; + return true; } else if (node->parent != lastidx) @@ -403,6 +409,8 @@ public: node->valset = true; new (&node->value) K(obj); + m_numElements++; + return true; } else @@ -421,6 +429,7 @@ public: { node->valset = true; new (&node->value) K(obj); + m_numElements++; return true; } /* Same string. We can't insert. */ @@ -605,6 +614,8 @@ public: } } + m_numElements++; + /* Phew! */ return true; } @@ -631,6 +642,7 @@ public: { node->valset = true; new (&node->value) K(obj); + m_numElements++; return true; } @@ -644,6 +656,7 @@ public: m_baseSize = 256; m_stSize = 256; m_empty = NULL; + m_numElements = 0; internal_clear(); } @@ -775,6 +788,7 @@ private: void internal_clear() { m_tail = 0; + m_numElements = 0; memset(m_base, 0, sizeof(KTrieNode) * (m_baseSize + 1)); memset(m_stringtab, 0, sizeof(char) * m_stSize); @@ -895,6 +909,10 @@ public: + m_stSize + sizeof(KTrieNode); } + size_t size() + { + return m_numElements; + } private: KTrieNode *m_base; /* Base array for the sparse tables */ KTrieNode *m_empty; /* Special case for empty strings */ @@ -902,6 +920,7 @@ private: unsigned int m_baseSize; /* Size of the base array, in members */ unsigned int m_stSize; /* Size of the string table, in bytes */ unsigned int m_tail; /* Current unused offset into the string table */ + size_t m_numElements; /* Number of elements in use */ }; /**