added bad trie iteration
--HG-- branch : sourcemod-1.0.1 extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%401963
This commit is contained in:
parent
1e1ebc981a
commit
adbd79633b
@ -90,3 +90,32 @@ size_t sm_trie_mem_usage(Trie *trie)
|
||||
{
|
||||
return trie->k.mem_usage();
|
||||
}
|
||||
|
||||
struct trie_iter_data
|
||||
{
|
||||
SM_TRIE_BAD_ITERATOR iter;
|
||||
void *ptr;
|
||||
Trie *pTrie;
|
||||
};
|
||||
|
||||
void our_trie_iterator(KTrie<void *> *pTrie, const char *name, void *& obj, void *data)
|
||||
{
|
||||
trie_iter_data *our_iter;
|
||||
|
||||
our_iter = (trie_iter_data *)data;
|
||||
our_iter->iter(our_iter->pTrie, name, &obj, our_iter->ptr);
|
||||
}
|
||||
|
||||
void sm_trie_bad_iterator(Trie *trie,
|
||||
char *buffer,
|
||||
size_t maxlength,
|
||||
SM_TRIE_BAD_ITERATOR iter,
|
||||
void *data)
|
||||
{
|
||||
trie_iter_data our_iter;
|
||||
|
||||
our_iter.iter = iter;
|
||||
our_iter.ptr = data;
|
||||
our_iter.pTrie = trie;
|
||||
trie->k.bad_iterator(buffer, maxlength, &our_iter, our_trie_iterator);
|
||||
}
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
struct Trie;
|
||||
|
||||
typedef void (*SM_TRIE_BAD_ITERATOR)(Trie *pTrie, const char *key, void **value, void *data);
|
||||
|
||||
Trie *sm_trie_create();
|
||||
void sm_trie_destroy(Trie *trie);
|
||||
bool sm_trie_insert(Trie *trie, const char *key, void *value);
|
||||
@ -42,5 +44,10 @@ bool sm_trie_retrieve(Trie *trie, const char *key, void **value);
|
||||
bool sm_trie_delete(Trie *trie, const char *key);
|
||||
void sm_trie_clear(Trie *trie);
|
||||
size_t sm_trie_mem_usage(Trie *trie);
|
||||
void sm_trie_bad_iterator(Trie *trie,
|
||||
char *buffer,
|
||||
size_t maxlength,
|
||||
SM_TRIE_BAD_ITERATOR iter,
|
||||
void *data);
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_SIMPLE_TRIE_H_
|
||||
|
@ -648,6 +648,117 @@ public:
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterates over the trie returning all known values.
|
||||
*
|
||||
* Note: This function is for debugging. Do not use it as a
|
||||
* production iterator since it's inefficient. Iteration is
|
||||
* guaranteed to be sorted ascendingly.
|
||||
*
|
||||
* The callback function takes:
|
||||
* (KTrie) - Pointer to this Trie
|
||||
* (const char *) - String containing key name.
|
||||
* (K &) - By-reference object at the key.
|
||||
* (data) - User pointer.
|
||||
*
|
||||
* @param buffer Buffer to use as a key name cache.
|
||||
* @param maxlength Maximum length of the key name buffer.
|
||||
* @param data User pointer for passing to the iterator.
|
||||
* @param func Iterator callback function.
|
||||
*/
|
||||
void bad_iterator(char *buffer,
|
||||
size_t maxlength,
|
||||
void *data,
|
||||
void (*func)(KTrie *, const char *, K & obj, void *data))
|
||||
{
|
||||
bad_iterator_r(buffer, maxlength, 0, data, func, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
void bad_iterator_r(char *buffer,
|
||||
size_t maxlength,
|
||||
size_t buf_pos,
|
||||
void *data,
|
||||
void (*func)(KTrie *, const char *, K & obj, void *data),
|
||||
unsigned int root)
|
||||
{
|
||||
char *term;
|
||||
unsigned int idx, limit, start;
|
||||
|
||||
limit = 255;
|
||||
start = m_base[root].idx;
|
||||
|
||||
/* Bound our limits */
|
||||
if (start + limit > m_baseSize)
|
||||
{
|
||||
limit = m_baseSize - start;
|
||||
}
|
||||
|
||||
/* Search for strings */
|
||||
for (unsigned int i = 1; i <= limit; i++)
|
||||
{
|
||||
idx = start + i;
|
||||
if (m_base[idx].mode == Node_Unused
|
||||
|| m_base[idx].parent != root)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_base[idx].mode == Node_Arc)
|
||||
{
|
||||
if (buf_pos < maxlength - 1)
|
||||
{
|
||||
buffer[buf_pos++] = (char)i;
|
||||
}
|
||||
|
||||
if (m_base[idx].valset)
|
||||
{
|
||||
buffer[buf_pos] = '\0';
|
||||
func(this, buffer, m_base[idx].value, data);
|
||||
}
|
||||
|
||||
bad_iterator_r(buffer,
|
||||
maxlength,
|
||||
buf_pos,
|
||||
data,
|
||||
func,
|
||||
idx);
|
||||
|
||||
buf_pos--;
|
||||
}
|
||||
else if (m_base[idx].mode == Node_Term
|
||||
&& m_base[idx].valset == true)
|
||||
{
|
||||
size_t save_buf_pos;
|
||||
|
||||
save_buf_pos = buf_pos;
|
||||
if (buf_pos < maxlength - 1)
|
||||
{
|
||||
buffer[buf_pos++] = (char)i;
|
||||
}
|
||||
if (buf_pos < maxlength - 1)
|
||||
{
|
||||
size_t destlen, j;
|
||||
|
||||
term = &m_stringtab[m_base[idx].idx];
|
||||
destlen = strlen(term);
|
||||
for (j = 0;
|
||||
j < destlen && j + buf_pos < maxlength - 1;
|
||||
j++)
|
||||
{
|
||||
buffer[buf_pos + j] = term[j];
|
||||
}
|
||||
buf_pos += j;
|
||||
}
|
||||
buffer[buf_pos] = '\0';
|
||||
|
||||
func(this, buffer, m_base[idx].value, data);
|
||||
|
||||
buf_pos = save_buf_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
KTrie()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user