/** * 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); }
/** * 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; }