mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / mysys / trie.c
blob36becb7f9d8f77c66912ed17f517c745834dc5fb
1 /* Copyright (c) 2005-2007 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17 Implementation of trie and Aho-Corasick automaton.
18 Supports only charsets that can be compared byte-wise.
20 TODO:
21 Add character frequencies. Can increase lookup speed
22 up to 30%.
23 Implement character-wise comparision.
27 #include "mysys_priv.h"
28 #include <m_string.h>
29 #include <my_trie.h>
30 #include <my_base.h>
34 SYNOPSIS
35 TRIE *trie_init (TRIE *trie, CHARSET_INFO *charset);
37 DESCRIPTION
38 Allocates or initializes a `TRIE' object. If `trie' is a `NULL'
39 pointer, the function allocates, initializes, and returns a new
40 object. Otherwise, the object is initialized and the address of
41 the object is returned. If `trie_init()' allocates a new object,
42 it will be freed when `trie_free()' is called.
44 RETURN VALUE
45 An initialized `TRIE*' object. `NULL' if there was insufficient
46 memory to allocate a new object.
49 TRIE *trie_init (TRIE *trie, CHARSET_INFO *charset)
51 MEM_ROOT mem_root;
52 DBUG_ENTER("trie_init");
53 DBUG_ASSERT(charset);
54 init_alloc_root(&mem_root,
55 (sizeof(TRIE_NODE) * 128) + ALLOC_ROOT_MIN_BLOCK_SIZE,
56 sizeof(TRIE_NODE) * 128);
57 if (! trie)
59 if (! (trie= (TRIE *)alloc_root(&mem_root, sizeof(TRIE))))
61 free_root(&mem_root, MYF(0));
62 DBUG_RETURN(NULL);
66 memcpy(&trie->mem_root, &mem_root, sizeof(MEM_ROOT));
67 trie->root.leaf= 0;
68 trie->root.c= 0;
69 trie->root.next= NULL;
70 trie->root.links= NULL;
71 trie->root.fail= NULL;
72 trie->charset= charset;
73 trie->nnodes= 0;
74 trie->nwords= 0;
75 DBUG_RETURN(trie);
80 SYNOPSIS
81 void trie_free (TRIE *trie);
82 trie - valid pointer to `TRIE'
84 DESCRIPTION
85 Frees the memory allocated for a `trie'.
87 RETURN VALUE
88 None.
91 void trie_free (TRIE *trie)
93 MEM_ROOT mem_root;
94 DBUG_ENTER("trie_free");
95 DBUG_ASSERT(trie);
96 memcpy(&mem_root, &trie->mem_root, sizeof(MEM_ROOT));
97 free_root(&mem_root, MYF(0));
98 DBUG_VOID_RETURN;
103 SYNOPSIS
104 my_bool trie_insert (TRIE *trie, const uchar *key, uint keylen);
105 trie - valid pointer to `TRIE'
106 key - valid pointer to key to insert
107 keylen - non-0 key length
109 DESCRIPTION
110 Inserts new key into trie.
112 RETURN VALUE
113 Upon successful completion, `trie_insert' returns `FALSE'. Otherwise
114 `TRUE' is returned.
116 NOTES
117 If this function fails you must assume `trie' is broken.
118 However it can be freed with trie_free().
121 my_bool trie_insert (TRIE *trie, const uchar *key, uint keylen)
123 TRIE_NODE *node;
124 TRIE_NODE *next;
125 uchar p;
126 uint k;
127 DBUG_ENTER("trie_insert");
128 DBUG_ASSERT(trie && key && keylen);
129 node= &trie->root;
130 trie->root.fail= NULL;
131 for (k= 0; k < keylen; k++)
133 p= key[k];
134 for (next= node->links; next; next= next->next)
135 if (next->c == p)
136 break;
138 if (! next)
140 TRIE_NODE *tmp= (TRIE_NODE *)alloc_root(&trie->mem_root,
141 sizeof(TRIE_NODE));
142 if (! tmp)
143 DBUG_RETURN(TRUE);
144 tmp->leaf= 0;
145 tmp->c= p;
146 tmp->links= tmp->fail= tmp->next= NULL;
147 trie->nnodes++;
148 if (! node->links)
150 node->links= tmp;
152 else
154 for (next= node->links; next->next; next= next->next) /* no-op */;
155 next->next= tmp;
157 node= tmp;
159 else
161 node= next;
164 node->leaf= keylen;
165 trie->nwords++;
166 DBUG_RETURN(FALSE);
171 SYNOPSIS
172 my_bool trie_prepare (TRIE *trie);
173 trie - valid pointer to `TRIE'
175 DESCRIPTION
176 Constructs Aho-Corasick automaton.
178 RETURN VALUE
179 Upon successful completion, `trie_prepare' returns `FALSE'. Otherwise
180 `TRUE' is returned.
183 my_bool ac_trie_prepare (TRIE *trie)
185 TRIE_NODE **tmp_nodes;
186 TRIE_NODE *node;
187 uint32 fnode= 0;
188 uint32 lnode= 0;
189 DBUG_ENTER("trie_prepare");
190 DBUG_ASSERT(trie);
192 tmp_nodes= (TRIE_NODE **)my_malloc(trie->nnodes * sizeof(TRIE_NODE *), MYF(0));
193 if (! tmp_nodes)
194 DBUG_RETURN(TRUE);
196 trie->root.fail= &trie->root;
197 for (node= trie->root.links; node; node= node->next)
199 node->fail= &trie->root;
200 tmp_nodes[lnode++]= node;
203 while (fnode < lnode)
205 TRIE_NODE *current= (TRIE_NODE *)tmp_nodes[fnode++];
206 for (node= current->links; node; node= node->next)
208 TRIE_NODE *fail= current->fail;
209 tmp_nodes[lnode++]= node;
210 while (! (node->fail= trie_goto(&trie->root, fail, node->c)))
211 fail= fail->fail;
214 my_free((uchar*)tmp_nodes, MYF(0));
215 DBUG_RETURN(FALSE);
220 SYNOPSIS
221 void ac_trie_init (TRIE *trie, AC_TRIE_STATE *state);
222 trie - valid pointer to `TRIE'
223 state - value pointer to `AC_TRIE_STATE'
225 DESCRIPTION
226 Initializes `AC_TRIE_STATE' object.
229 void ac_trie_init (TRIE *trie, AC_TRIE_STATE *state)
231 DBUG_ENTER("ac_trie_init");
232 DBUG_ASSERT(trie && state);
233 state->trie= trie;
234 state->node= &trie->root;
235 DBUG_VOID_RETURN;