aboutsummaryrefslogtreecommitdiffstats
path: root/src/trie.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-04-21 16:25:51 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-04-21 16:25:51 +0100
commit61555065f3d1c8badcc9573691232f1b6e42988c (patch)
tree563d5b7cb8c468530f7e79c4da0a75267b1184e1 /src/trie.c
parentad5bf825b7f33bc10311673991f0cc888e69c0b1 (diff)
downloadrspamd-61555065f3d1c8badcc9573691232f1b6e42988c.tar.gz
rspamd-61555065f3d1c8badcc9573691232f1b6e42988c.zip
Rework project structure, remove trash files.
Diffstat (limited to 'src/trie.c')
-rw-r--r--src/trie.c230
1 files changed, 0 insertions, 230 deletions
diff --git a/src/trie.c b/src/trie.c
deleted file mode 100644
index 394c4e939..000000000
--- a/src/trie.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright (c) 2010, Vsevolod Stakhov
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "mem_pool.h"
-#include "trie.h"
-
-rspamd_trie_t*
-rspamd_trie_create (gboolean icase)
-{
- rspamd_trie_t *new;
-
- new = g_malloc (sizeof (rspamd_trie_t));
-
- new->icase = icase;
- new->pool = rspamd_mempool_new (rspamd_mempool_suggest_size ());
- new->root.fail = NULL;
- new->root.final = 0;
- new->root.id = 0;
- new->root.next = NULL;
- new->root.match = NULL;
- new->fail_states = g_ptr_array_sized_new (8);
-
- return new;
-}
-
-/*
- * Insert a single character as the specified level of the suffix tree
- */
-static struct rspamd_trie_state *
-rspamd_trie_insert_char (rspamd_trie_t *trie, guint depth, struct rspamd_trie_state *pos, gchar c)
-{
- struct rspamd_trie_match *new_match;
- struct rspamd_trie_state *new_pos;
-
- /* New match is inserted before pos */
- new_match = rspamd_mempool_alloc (trie->pool, sizeof (struct rspamd_trie_match));
- new_match->next = pos->match;
- new_match->c = c;
-
- /* Now set match link */
- pos->match = new_match;
-
- new_match->state = rspamd_mempool_alloc (trie->pool, sizeof (struct rspamd_trie_state));
- new_pos = new_match->state;
- new_pos->match = NULL;
- new_pos->fail = &trie->root;
- new_pos->final = 0;
- new_pos->id = -1;
-
- if (trie->fail_states->len < depth + 1) {
- /* Grow fail states array if depth is more than its size */
- guint size = trie->fail_states->len;
-
- size = MAX (size * 2, depth + 1);
- g_ptr_array_set_size (trie->fail_states, size);
- }
-
- new_pos->next = trie->fail_states->pdata[depth];
- trie->fail_states->pdata[depth] = new_pos;
-
- return new_pos;
-}
-
-/* Traverse the specified node to find corresponding match */
-static inline struct rspamd_trie_match *
-check_match (struct rspamd_trie_state *s, gchar c)
-{
- struct rspamd_trie_match *match = s->match;
-
- while (match && match->c != c) {
- match = match->next;
- }
-
- return match;
-}
-
-void
-rspamd_trie_insert (rspamd_trie_t *trie, const gchar *pattern, gint pattern_id)
-{
- const guchar *p = pattern;
- struct rspamd_trie_state *q, *q1, *r, *cur_node;
- struct rspamd_trie_match *m, *n;
- guint i, depth = 0;
- gchar c;
-
- /* Insert pattern to the trie */
-
- cur_node = &trie->root;
-
- while (*p) {
- c = trie->icase ? g_ascii_tolower (*p) : *p;
- m = check_match (cur_node, c);
- if (m == NULL) {
- /* Insert a character at specified level depth */
- cur_node = rspamd_trie_insert_char (trie, depth, cur_node, c);
- }
- else {
- cur_node = m->state;
- }
- p ++;
- depth ++;
- }
-
- cur_node->final = depth;
- cur_node->id = pattern_id;
-
- /* Update fail states and build fail states graph */
- /* Go through the whole depth of prefixes */
- for (i = 0; i < trie->fail_states->len; i++) {
- q = trie->fail_states->pdata[i];
- while (q) {
- m = q->match;
- while (m) {
- c = m->c;
- q1 = m->state;
- r = q->fail;
- /* Move q->fail to last known fail location for this character (or to NULL) */
- while (r && (n = check_match (r, c)) == NULL) {
- r = r->fail;
- }
-
- /* We have found new fail location for character c, so set it in q1 */
- if (r != NULL) {
- q1->fail = n->state;
- if (q1->fail->final > q1->final) {
- q1->final = q1->fail->final;
- }
- }
- else {
- /* Search from root */
- if ((n = check_match (&trie->root, c))) {
- q1->fail = n->state;
- }
- else {
- q1->fail = &trie->root;
- }
- }
-
- m = m->next;
- }
-
- q = q->next;
- }
- }
-}
-
-const gchar*
-rspamd_trie_lookup (rspamd_trie_t *trie, const gchar *buffer, gsize buflen, gint *matched_id)
-{
- const guchar *p = buffer, *prev, *ret;
- struct rspamd_trie_state *cur_node;
- struct rspamd_trie_match *m = NULL;
- gchar c;
-
-
- cur_node = &trie->root;
- prev = p;
- ret = p;
-
- while (buflen) {
- c = trie->icase ? g_ascii_tolower (*p) : *p;
-
- /* Match pattern or use fail-path to restore state */
- while (cur_node != NULL && (m = check_match (cur_node, c)) == NULL) {
- cur_node = cur_node->fail;
- }
-
- /* Shift left in the text */
- if (cur_node == &trie->root) {
- /* 1 character pattern found */
- ret = prev;
- }
- else if (cur_node == NULL) {
- /* We have tried the pattern but eventually it was not found */
- cur_node = &trie->root;
- ret = p;
- p ++;
- prev = p;
- buflen --;
- continue;
- }
-
- if (m != NULL) {
- /* Match found */
- cur_node = m->state;
-
- if (cur_node->final) {
- /* The complete pattern found */
- if (matched_id != NULL) {
- *matched_id = cur_node->id;
- }
- return (const gchar *) ret;
- }
- }
- p ++;
- prev = p;
- buflen --;
- }
-
- return NULL;
-}
-
-void
-rspamd_trie_free (rspamd_trie_t *trie)
-{
- g_ptr_array_free (trie->fail_states, TRUE);
- rspamd_mempool_delete (trie->pool);
- g_free (trie);
-}