Example #1
0
/**
 * Add items to the bintree for fast goto() transitions. Recursive calls
 *
 * @param states states array sorted by it's letter
 * @param lb left branch index
 * @param rb right branch index
 * @param pos current position
 * @param pool the memory pool to use
 *
 * @return ib_status_t status of the operation
 */
static ib_status_t ib_ac_add_bintree_sorted(ib_ac_bintree_t *state,
                                  ib_ac_state_t *states[],
                                  int pos,
                                  int lb,
                                  int rb,
                                  ib_mpool_t *pool)
{
    IB_FTRACE_INIT();
    ib_status_t st;
    int left = 0;
    int right = 0;

    if ((pos - lb) > 1) {
        left = lb + (pos - lb) / 2;
        state->left = (ib_ac_bintree_t *)ib_mpool_calloc(pool, 1,
                                                   sizeof(ib_ac_bintree_t));
        if (state->left == NULL) {
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }

        state->left->state = states[left];
        state->left->letter = states[left]->letter;
    }

    if ((rb - pos) > 1) {
        right = pos + (rb - pos) / 2;
        state->right = (ib_ac_bintree_t *)ib_mpool_calloc(pool, 1,
                                                   sizeof(ib_ac_bintree_t));
        if (state->right == NULL) {
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }

        state->right->state = states[right];
        state->right->letter = states[right]->letter;
    }

    if (state->right != NULL) {
        st = ib_ac_add_bintree_sorted(state->right, states, right,
                                      pos, rb, pool);
        if (st != IB_OK) {
            IB_FTRACE_RET_STATUS(st);
        }

    }

    if (state->left != NULL) {
        st = ib_ac_add_bintree_sorted(state->left, states, left, lb,
                                      pos, pool);
        if (st != IB_OK) {
            IB_FTRACE_RET_STATUS(st);
        }
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Example #2
0
/**
 * Builds balanced binary tree of the children states of the given state
 *
 * @param ac_tree the ac tree matcher
 * @param state the parent state
 *
 * @return ib_status_t status of the operation
 */
static ib_status_t ib_ac_build_bintree(ib_ac_t *ac_tree,
                                       ib_ac_state_t *state)
{
    ib_ac_state_t *child = state->child;
    ib_ac_state_t **states = NULL;

    size_t count = 0;
    size_t pos = 0;

    size_t i = 0;
    size_t j = 0;

    for (count = 0;
         child != NULL;
         child = child->sibling)
    {
        ++count;
    }

    states = (ib_ac_state_t **)ib_mpool_calloc(ac_tree->mp, count,
                                             sizeof(ib_ac_state_t *));

    if (states == NULL) {
        return IB_EALLOC;
    }

    child = state->child;
    for (i = 0; i < count; ++i) {
        states[i] = child;
        child = child->sibling;
    }

    for (i = 0; i < count - 1; ++i) {
        for (j = i + 1; j < count; ++j) {
            ib_ac_state_t *tmp;

            if (states[i]->letter < states[j]->letter) {
                continue;
            }

            tmp = states[i];
            states[i] = states[j];
            states[j] = tmp;
        }
    }

    state->bintree = (ib_ac_bintree_t *)ib_mpool_calloc(ac_tree->mp,
                                                1, sizeof(ib_ac_bintree_t));

    if (state->bintree == NULL) {
        return IB_EALLOC;
    }

    pos = count / 2;
    state->bintree->state = states[pos];
    state->bintree->letter = states[pos]->letter;
    ib_ac_add_bintree_sorted(state->bintree, states, pos, -1, count,
                                      ac_tree->mp);

    for (i = 0; i < count; ++i) {
        if (states[i]->child != NULL) {
            ib_ac_build_bintree(ac_tree, states[i]);
        }
    }

    return IB_OK;
}