cleaned up the Trie code a bit by unifying retrieval into one internal function

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401390
This commit is contained in:
David Anderson 2007-08-29 02:37:25 +00:00
parent 97196e70be
commit 07037e3fa2
2 changed files with 32 additions and 60 deletions

View File

@ -107,13 +107,6 @@
* This would drastically speed up x_check* * This would drastically speed up x_check*
*/ */
enum NodeType
{
Node_Unused = 0, /* Node is not being used (sparse) */
Node_Arc, /* Node is part of an arc and does not terminate */
Node_Term, /* Node is a terminator */
};
struct TrieNode struct TrieNode
{ {
/** /**
@ -303,7 +296,7 @@ void sm_trie_destroy(Trie *trie)
delete trie; delete trie;
} }
bool sm_trie_delete(Trie *trie, const char *key) TrieNode *sm_trie_internal_retrieve(Trie *trie, const char *key)
{ {
unsigned int lastidx = 1; /* the last node index */ unsigned int lastidx = 1; /* the last node index */
unsigned int curidx; /* current node index */ unsigned int curidx; /* current node index */
@ -313,7 +306,7 @@ bool sm_trie_delete(Trie *trie, const char *key)
if (!*key) if (!*key)
{ {
return false; return NULL;
} }
/* Start traversing at the root node */ /* Start traversing at the root node */
@ -329,7 +322,7 @@ bool sm_trie_delete(Trie *trie, const char *key)
/* Check if this slot is supposed to be empty or is a collision */ /* Check if this slot is supposed to be empty or is a collision */
if ((curidx > trie->baseSize) || node->mode == Node_Unused || node->parent != lastidx) if ((curidx > trie->baseSize) || node->mode == Node_Unused || node->parent != lastidx)
{ {
return false; return NULL;
} else if (node->mode == Node_Term) { } else if (node->mode == Node_Term) {
char *term = &trie->stringtab[node->idx]; char *term = &trie->stringtab[node->idx];
if (strcmp(keyptr, term) == 0) if (strcmp(keyptr, term) == 0)
@ -340,59 +333,27 @@ bool sm_trie_delete(Trie *trie, const char *key)
lastidx = curidx; lastidx = curidx;
} while (*keyptr != '\0'); } while (*keyptr != '\0');
assert(node != NULL); return node;
}
if (!node->valset) bool sm_trie_delete(Trie *trie, const char *key)
{
TrieNode *node = sm_trie_internal_retrieve(trie, key);
if (!node || !node->valset)
{ {
return false; return false;
} }
node->valset = false;
node->value = NULL; node->value = NULL;
node->valset = false;
return true; return true;
} }
bool sm_trie_retrieve(Trie *trie, const char *key, void **value) bool sm_trie_retrieve(Trie *trie, const char *key, void **value)
{ {
unsigned int lastidx = 1; /* the last node index */ TrieNode *node = sm_trie_internal_retrieve(trie, key);
unsigned int curidx; /* current node index */ if (!node || !node->valset)
const char *keyptr = key; /* input stream at current token */
TrieNode *node = NULL; /* current node being processed */
TrieNode *base = trie->base;
if (!*key)
{
return false;
}
/* Start traversing at the root node */
do
{
/* Find where the next character is, then advance */
curidx = base[lastidx].idx;
node = &base[curidx];
curidx += charval(*keyptr);
node = &base[curidx];
keyptr++;
/* Check if this slot is supposed to be empty or is a collision */
if ((curidx > trie->baseSize) || node->mode == Node_Unused || node->parent != lastidx)
{
return false;
} else if (node->mode == Node_Term) {
char *term = &trie->stringtab[node->idx];
if (strcmp(keyptr, term) == 0)
{
break;
}
}
lastidx = curidx;
} while (*keyptr != '\0');
assert(node != NULL);
if (!node->valset)
{ {
return false; return false;
} }
@ -405,7 +366,7 @@ bool sm_trie_retrieve(Trie *trie, const char *key, void **value)
return true; return true;
} }
bool sm_trie_add(Trie *trie, const char *key, void *value, bool replace_allowed) bool sm_trie_insert(Trie *trie, const char *key, void *value)
{ {
unsigned int lastidx = 1; /* the last node index */ unsigned int lastidx = 1; /* the last node index */
unsigned int curidx; /* current node index */ unsigned int curidx; /* current node index */
@ -650,7 +611,7 @@ bool sm_trie_add(Trie *trie, const char *key, void *value, bool replace_allowed)
/* Do an initial browsing to make sure they're not the same string */ /* Do an initial browsing to make sure they're not the same string */
if (strcmp(keyptr, term) == 0) if (strcmp(keyptr, term) == 0)
{ {
if (!node->valset || replace_allowed) if (!node->valset)
{ {
node->valset = true; node->valset = true;
node->value = value; node->value = value;
@ -830,7 +791,7 @@ bool sm_trie_add(Trie *trie, const char *key, void *value, bool replace_allowed)
*/ */
assert(node->mode == Node_Arc); assert(node->mode == Node_Arc);
if (!node->valset || replace_allowed) if (!node->valset)
{ {
/* Insert is only possible if we have no production */ /* Insert is only possible if we have no production */
node->valset = true; node->valset = true;
@ -841,12 +802,16 @@ bool sm_trie_add(Trie *trie, const char *key, void *value, bool replace_allowed)
return false; return false;
} }
bool sm_trie_insert(Trie *trie, const char *key, void *value)
{
return sm_trie_add(trie, key, value, false);
}
bool sm_trie_replace(Trie *trie, const char *key, void *value) bool sm_trie_replace(Trie *trie, const char *key, void *value)
{ {
return sm_trie_add(trie, key, value, true); TrieNode *node = sm_trie_internal_retrieve(trie, key);
if (!node)
{
return sm_trie_insert(trie, key, value);
}
node->value = value;
node->valset = true;
return true;
} }

View File

@ -34,6 +34,13 @@
struct Trie; struct Trie;
enum NodeType
{
Node_Unused = 0, /* Node is not being used (sparse) */
Node_Arc, /* Node is part of an arc and does not terminate */
Node_Term, /* Node is a terminator */
};
Trie *sm_trie_create(); Trie *sm_trie_create();
void sm_trie_destroy(Trie *trie); void sm_trie_destroy(Trie *trie);
bool sm_trie_insert(Trie *trie, const char *key, void *value); bool sm_trie_insert(Trie *trie, const char *key, void *value);