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:
parent
97196e70be
commit
07037e3fa2
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user