void remove_cell_from_node(b_tree_node *n, b_tree_cell *cell) { if (n != nullptr && cell != nullptr) { b_tree_cell *old_header = n->header; n->erase(cell); if (old_header != n->header) { refresh_index_upwards(n); } if (n->size < (B_TREE_ORDER + 1) / 2 && n->pcell) { b_tree_node *target; if (n->pcell->next != nullptr) { target = n; merge_node(target, n->pcell->next->child); split_node(target); } else if (n->pcell->previous != nullptr) { target = n->pcell->previous->child; merge_node(target, n); split_node(target); } } while (root->size == 1 && root->header->child) { b_tree_node *t = root; root = root->header->child; root->pcell = nullptr; root->pnode = nullptr; delete t->header; delete t; } } }
static void btree_insert_nonfull(struct btree_s *tree, struct bnode_s *node, int k) { if (node->leaf) { int i = node->nkeys-1; while (i >= 0 && k < node->key[i]) { node->key[i+1] = node->key[i]; i--; } node->key[i+1] = k; node->nkeys++; } else { int i = node->nkeys-1; while (i >= 0 && k < node->key[i]) { i--; } int child_pos = RIGHT_CHILD_OF_KEY(i); /* 插入到这个key有边的child的位置 */ if (node->child[child_pos]->nkeys == tree->max_key_nr) { split_node(tree, node, child_pos); if (k > node->key[RIGHT_KEY_OF_CHILD(child_pos)]) { /* 新插入的key在这个child的右边 */ /* 插入到新的孩子节点 */ child_pos++; } } btree_insert_nonfull(tree, node->child[child_pos], k); } }
//{{{void test_split_node_non_root_parent_has_room(void) void test_split_node_root(void) { int V[5] = {2,3,4,5,6}; struct node *root = new_node(); root->is_leaf = 1; root->num_keys = 5; root->keys[0] = 1; root->keys[1] = 2; root->keys[2] = 3; root->keys[3] = 4; root->keys[4] = 5; root->pointers[0] = (void*)V; root->pointers[1] = (void*)(V + 1); root->pointers[2] = (void*)(V + 2); root->pointers[3] = (void*)(V + 2); root->pointers[4] = (void*)(V + 3); struct node *p_root = root; struct node *new_root = split_node(root, p_root); TEST_ASSERT_EQUAL(2, p_root->num_keys); TEST_ASSERT_EQUAL(3, p_root->next->num_keys); }
/* add_element() - add the record with the specified key to the B-tree. * returns a pointer to an already existing record with the same key, * in which case, the new record was not inserted, or NULL on success * should be no need to modify this function */ nodevalue * add_element(nodekey key, nodevalue * pvalue) { /* find leaf */ p_tnode pleaf = ptreeroot, parent = NULL; int ichild, i; while (pleaf != NULL) { ichild = find_index(key, pleaf); if (ichild < 0) /* already exists */ return pleaf->values[-(ichild+1)]; if (pleaf->nkeys == 2*T-1) { /* split leaf into two nodes */ split_node(&pleaf, &ichild); } parent = pleaf; pleaf = pleaf->children[ichild]; } pleaf = parent; record_count++; /* record actually added to tree */ /* enough room, just add to leaf */ for (i = pleaf->nkeys; i > ichild; i--) { pleaf->keys[i] = pleaf->keys[i-1]; pleaf->values[i] = pleaf->values[i-1]; } pleaf->keys[ichild] = key; pleaf->values[ichild] = pvalue; pleaf->nkeys++; return NULL; }
// if the root is leaf, insert key into root directly. // otherwise, find the proper child to insert the key. void tree_insert_nofull(tree_node *root, int key) { int i = 0; while((i < root->keynum)&&(key > root->key[i])) i++; if(root->leaf == 1) { int j; for(j = root->keynum; j > i; j--) root->key[j] = root->key[j-1]; root->key[i] = key; root->keynum++; } else { if(root->children[i]->keynum == 3) { split_node(root, i, root->children[i]); if(key > root->key[i]) i++; } tree_insert_nofull(root->children[i], key); } }
static int insert_branch ( tree_s *tree, branch_s *parent, u32 key, void *rec, unint size) { void *child; s64 k; /* Critical that this be signed */ FN; for (;;) { do { k = binary_search_branch(key, parent->br_key, parent->br_num); child = parent->br_key[k].k_node; if (!child) { return qERR_NOT_FOUND; } } while (split_node(tree, parent, child, k, size)); if (magic(child) != BRANCH) { return insert_node(tree, child, key, rec, size); } parent = child; } }
// BSP Splitting nodes function BSP_node* BSPTree::split_node(ObjectList objects, BoundingBox box,int depth) { // creating a new node and root (if not already made) BSP_node *node = new BSP_node(); if ((depth<=0) || (objects.size()<=MaxObjsPerNode)){ node->is_leaf = true; node->obj_array = objects; node->left = NULL; node->right = NULL; return node; } // find the split position Plane_Cut bestCut = getBestCut(objects,box); // bad axis if cost is higher to split if (bestCut.axis<0){ node->is_leaf = true; node->obj_array = objects; node->left = NULL; node->right = NULL; return node; } // assign cut node->axis = bestCut.axis; node->plane_pos = bestCut.pos; node->is_leaf = false; // get above and blow bounding box BoundingBox below = getBelowBoundingBox(box,node->axis,node->plane_pos); BoundingBox above = getAboveBoundingBox(box,node->axis,node->plane_pos); // finding objects in each box ObjectList objsAbove = objsInBox(objects,above); ObjectList objsBelow = objsInBox(objects,below); // split further node->left = split_node(objsBelow,below,depth-1); node->right = split_node(objsAbove,above,depth-1); // return this node (thats now been split into a tree) return node; }
//插入到一个非空节点 void insert_nonfull(bnode * node, int data) { //如果是叶子节点,则直接插入 if(node -> isleaf == true) { //得到节点的key的数组的最大索引值 int i = node -> keynum - 1; /** * 开始比较要插入的data * 如果data小于当前结点的key,则所有的key往后移:i+1 <= i * 最后吧data放到最终确定的位置,也就是把data放到node中最小的key的位置 */ while( i >= 0 && data < node -> keys[i]) { node -> keys[i+1] = node -> keys[i]; i--; } node -> keynum++; node -> keys[i+1] = data; } //如果不是叶子节点,则肯定不是插在这个节点,而是需要比较大小,插入到他的子节点中去 else { ///得到节点的key的数组的最大索引值 int i = node -> keynum - 1; //寻找,通过比较大小,看看被插入节点应该落在哪个位置 while( i >= 0 && data < node -> keys[i] ) { i--; } //往前进一步 i++; //如果这个子节点已经满了,那么简单,先分裂此节点 if(node -> children[i] -> keynum == 2*T - 1) { //分裂这个已满的i节点 split_node(node, i); //注意,分裂之后的节点,肯定有一个节点被提上来了,并且这个被提上来的节点位置为i,而且这个被提上来的节点可能小于也可能大于之前确定好的i,所以我们这里要比较一下 //如果被提上来的节点比我们要插入的节点要小的话,那么我们之前确定的位置i就要变更了,具体就是+1,往后挪一位 if(data > node -> keys[i]) { i++; } } //插入到这个(如果满了就是被分裂)(如果没满就是未满节点)中去 insert_nonfull(node -> children[i], data); } }
//{{{void test_split_node_non_root_parent_has_room(void) void test_split_node_non_root_parent_has_room(void) { int V[5] = {2,3,4,5,6}; struct node *l1 = new_node(); l1->is_leaf = 1; l1->num_keys = 4; l1->keys[0] = 1; l1->keys[1] = 2; l1->keys[2] = 3; l1->keys[3] = 4; l1->pointers[0] = (void*)V; l1->pointers[1] = (void*)(V + 1); l1->pointers[2] = (void*)(V + 2); l1->pointers[3] = (void*)(V + 2); struct node *n1 = new_node(); n1->keys[0] = 6; n1->num_keys = 1; n1->pointers[0] = (void *)l1; l1->parent = n1; struct node *root = new_node(); root->keys[0] = 9; root->num_keys = 1; root->pointers[0] = (void *)n1; n1->parent = root; l1->num_keys = 5; l1->keys[4] = 5; root = split_node(root, l1); TEST_ASSERT_EQUAL(2, l1->num_keys); TEST_ASSERT_EQUAL(3, l1->next->num_keys); TEST_ASSERT_EQUAL(2, n1->num_keys); int A_n1[2] = {3,6}; int i; for (i = 0; i < n1->num_keys; ++i) TEST_ASSERT_EQUAL(A_n1[i], n1->keys[i]); TEST_ASSERT_EQUAL(l1, find_leaf(root, 1)); TEST_ASSERT_EQUAL(l1, find_leaf(root, 2)); TEST_ASSERT_EQUAL(l1->next, find_leaf(root, 3)); TEST_ASSERT_EQUAL(l1->next, find_leaf(root, 4)); TEST_ASSERT_EQUAL(l1->next, find_leaf(root, 5)); TEST_ASSERT_EQUAL(l1, n1->pointers[0]); TEST_ASSERT_EQUAL(l1->next, n1->pointers[1]); }
/*! * \brief Split a node according to clusters. */ static void split_node (struct rtree_node *node) { int i; struct rtree_node *new_node; assert (node); assert (node->flags.is_leaf ? (void *) node->u.rects[M_SIZE]. bptr : (void *) node->u.kids[M_SIZE]); new_node = find_clusters (node); if (node->parent == NULL) /* split root node */ { struct rtree_node *second; second = (struct rtree_node *)calloc (1, sizeof (*second)); *second = *node; if (!second->flags.is_leaf) for (i = 0; i < M_SIZE; i++) if (second->u.kids[i]) second->u.kids[i]->parent = second; node->flags.is_leaf = 0; node->flags.manage = 0; second->parent = new_node->parent = node; node->u.kids[0] = new_node; node->u.kids[1] = second; for (i = 2; i < M_SIZE + 1; i++) node->u.kids[i] = NULL; adjust_bounds (node); sort_node (node); #ifdef SLOW_ASSERTS assert (__r_tree_is_good (node)); #endif return; } for (i = 0; i < M_SIZE; i++) if (!node->parent->u.kids[i]) break; node->parent->u.kids[i] = new_node; #ifdef SLOW_ASSERTS assert (__r_node_is_good (node)); assert (__r_node_is_good (new_node)); #endif if (i < M_SIZE) { #ifdef SLOW_ASSERTS assert (__r_node_is_good (node->parent)); #endif sort_node (node->parent); return; } split_node (node->parent); }
struct ip_node* add_node(struct ip_node *root,unsigned char *ip,int ip_len, struct ip_node **father,char *flag) { struct ip_node *node; struct ip_node *kid; int byte_pos; int exit; if (!root || !ip || !ip_len) return 0; node = root; byte_pos = 0; exit = 0; while (byte_pos<ip_len && !exit) { kid = node->children; while (kid && kid->byte!=(unsigned char)ip[byte_pos]) { kid = kid->next; } if (kid) { node = kid; byte_pos++; } else { exit = 1; } } DBG("Only first %d were mached!\n",byte_pos); if (byte_pos==ip_len) { /* we found the entire address */ if (node->leaf_hits<max_hits) node->leaf_hits++; if (flag) *flag = LEAF_NODE|(node->leaf_hits>=max_hits?RED_NODE:0); if (father) *father = 0; return node; } else { node->hits++; /* we have only a prefix of the address into the tree */ if ( node==root || node->hits>=max_hits) { /* we have to split the node */ if (flag) *flag = NEW_NODE ; DBG("Splitting node %p [%x]\n",node,node->byte); if (father) *father = node; return split_node(node,ip[byte_pos]); } else { /* we just had marked the node as hit */ if (flag) *flag = 0; if (father) *father = 0; return node; } } }
void insert(bnode * * root, int key) { //根节点为空,则直接放入根节点 if(*root == NULL) { bnode * new_root = (bnode *)malloc(sizeof(bnode)); new_root -> parent = NULL; new_root -> isleaf = true; new_root -> keynum = 1; for(int i=0; i < 2*T - 1; i++) { new_root -> keys[i] = 0; } for(int i=0; i < 2*T; i++) { new_root -> children[i] = NULL; } new_root -> keys[0] = key; *root = new_root; return; } //根节点满了 if((* root) -> keynum == 2*T - 1) { //新开辟一个节点,孩子节点指向根节点 bnode * tmp = (bnode *)malloc(sizeof(bnode)); tmp -> keynum = 0; for(int i=0; i < 2*T - 1; i++) { tmp -> keys[i] = 0; } for(int i=0; i < 2*T; i++) { tmp -> children[i] = NULL; } tmp -> children[0] = *root; //分裂这个子节点所指向当前根节点的新节点 split_node(tmp, 0); //将分裂后的节点设置为根节点 *root = tmp; insert_nonfull(*root, key); } else { insert_nonfull(*root, key); } }
void BSpaceTree::generate_tree(BSpaceNode* node) { //if splitting the node was successful, do the same to the newly //generated child nodes, if they're too big or with a 75% chance. if(split_node(node) != false) { if(node->left->width > max_size || node->left->height > max_size || rand() % 100 > 25) { generate_tree(node->left); } if(node->right->width > max_size || node->right->height > max_size || rand() % 100 > 25) { generate_tree(node->right); } } }
void btree_insert(struct btree_s *tree, int k) { struct bnode_s *r = tree->root; if (r->nkeys == tree->max_key_nr) { struct bnode_s *new_root = alloc_node(tree->max_key_nr, tree->max_child_nr); new_root->nkeys = 0; new_root->child[0] = r; new_root->leaf = 0; tree->root = new_root; split_node(tree, new_root, 0); } btree_insert_nonfull(tree, tree->root, k); }
/* * insert the key in the leaf of the tree, * in the process of going down, if one node is full * then split it. */ tree_node* tree_insert(tree_node *root, int key) { void tree_insert_nofull(tree_node*, int); if(root->keynum == 3) { tree_node *p = make_node(); p->leaf = 0; split_node(p, 0, root); root = p; tree_insert_nofull(p, key); } else tree_insert_nofull(root, key); return root; }
/* * Tries to grab a ptr to a free chunk of memory that exists in the current free list. * On failure, return NULL */ void *req_free_mem(size_t req_size) { if(req_size < 1) { return NULL; } MM_node *prev_node = malloc_head; MM_node *cur_node = malloc_head->next_free; while(cur_node != NULL) { if(cur_node->status == USED) { mm_malloc_had_a_problem(); } // We have enough memory in this chunk to split it into two pieces if(cur_node->size > req_size + SPLIT_MINIMUM) { MM_node *new_node = split_node(cur_node, req_size); prev_node->next_free = new_node; cur_node->next_free = NULL; return (void *)((char *)cur_node + NODE_HEADER_SIZE); } // Just enough memory in this chunk to return it. else if(cur_node->size > req_size) { cur_node->status = USED; prev_node->next_free = cur_node->next_free; cur_node->next_free = NULL; return (void *)((char *)cur_node + NODE_HEADER_SIZE); } else { prev_node = cur_node; cur_node = cur_node->next_free; } } return NULL; }
void insert_cell_to_node(b_tree_node *n, b_tree_cell *cell) { if (n != nullptr && cell != nullptr) { if (n->header == nullptr || cell->key < n->header->key) { n->push_front(cell); refresh_index_upwards(n); } else { b_tree_cell *itr = n->header; while (itr->next && cell->key >= itr->next->key) { itr = itr->next; } if (cell->key == itr->key) { std::swap(itr->value, cell->value); delete cell; } else { n->insert_after(itr, cell); } } split_node(n); } }
// ------------------------------------------------------------------------ // BSP Tree Creation // ------------------------------------------------------------------------ void BSPTree::buildBSPTree() { // get starting time srand(time(NULL)); time_t begin,end; time(&begin); // find max depth float max_depth = 3+1.3*(log((float)m_kObjects.size()) / log((float)2)); // float max_depth = 2; // starting tree Debug("Initializing tree with max depth %d \n",(int)max_depth); Debug("Splits to check are %d \n",nSplits); // create tree root = split_node(m_kObjects,box,max_depth); // finishing making tree time(&end); Debug("Time Taken to build tree %d \n",(int)difftime(end,begin)); }
void BTree<Key, Value>::split_node(typename BTree<Key, Value>::Node::Ptr node) { auto C = this->make_node(); C->is_leaf = node->is_leaf; auto pos_half_index = (node->vals_size / 2); auto midle = node->vals[pos_half_index]; auto vals_begin = pos_half_index; // copy midlle?! if (!C->is_leaf) { vals_begin++; } // copy node.keys[midle,end] size_t insert_pos = 0; for (size_t i = vals_begin; i < node->vals_size; i++) { C->vals[insert_pos] = node->vals[i]; C->vals_size++; insert_pos++; } //node.keys[begin,midle) node->vals_size = pos_half_index; auto tmp = node->next; node->next = C->id; C->next = tmp; if (node->childs_size > 0) {// merge childs size_t new_count = node->childs_size / 2; C->childs_size = new_count; size_t pos = 0; for (size_t i = new_count; i < node->childs_size; i++) { auto ch_ind = node->childs[i]; auto ch = getNode(ch_ind); ch->parent = C->id; C->childs[pos++] = ch_ind; } for (size_t i = new_count; i < node->childs_size; i++) { node->childs[i] = 0; } node->childs_size = new_count; } typename Node::Ptr node2insert = nullptr; auto parent_ind = node->parent; if (parent_ind != 0) { //put to parent node2insert = getNode(parent_ind); node2insert->insertValue(midle.first, midle.second); node2insert->insertChild(midle.first, C); C->parent = node->parent; } else { //parent new root node2insert = this->make_node(); m_root->parent = node2insert->id; m_root = node2insert; node2insert->insertValue(midle.first, midle.second); node2insert->childs[node2insert->childs_size] = (node->id); node2insert->childs_size++; node2insert->childs[node2insert->childs_size] = (C->id); node2insert->childs_size++; node->parent = m_root->id; C->parent = m_root->id; } if (isFull(node2insert)) { split_node(node2insert); } }
static void __r_insert_node (struct rtree_node *node, const BoxType * query, int manage, bool force) { #ifdef SLOW_ASSERTS assert (__r_node_is_good (node)); #endif /* Ok, at this point we must already enclose the query or we're forcing * this node to expand to enclose it, so if we're a leaf, simply store * the query here */ if (node->flags.is_leaf) { register int i; if (UNLIKELY (manage)) { register int flag = 1; for (i = 0; i < M_SIZE; i++) { if (!node->u.rects[i].bptr) break; flag <<= 1; } node->flags.manage |= flag; } else { for (i = 0; i < M_SIZE; i++) if (!node->u.rects[i].bptr) break; } /* the node always has an extra space available */ node->u.rects[i].bptr = query; node->u.rects[i].bounds = *query; /* first entry in node determines initial bounding box */ if (i == 0) node->box = *query; else if (force) { MAKEMIN (node->box.X1, query->X1); MAKEMAX (node->box.X2, query->X2); MAKEMIN (node->box.Y1, query->Y1); MAKEMAX (node->box.Y2, query->Y2); } if (i < M_SIZE) { sort_node (node); return; } /* we must split the node */ split_node (node); return; } else { int i; struct rtree_node *best_node; double score, best_score; if (force) { MAKEMIN (node->box.X1, query->X1); MAKEMAX (node->box.X2, query->X2); MAKEMIN (node->box.Y1, query->Y1); MAKEMAX (node->box.Y2, query->Y2); } /* this node encloses it, but it's not a leaf, so descend the tree */ /* First check if any children actually encloses it */ assert (node->u.kids[0]); for (i = 0; i < M_SIZE; i++) { if (!node->u.kids[i]) break; if (contained (node->u.kids[i], query)) { __r_insert_node (node->u.kids[i], query, manage, false); sort_node (node); return; } } /* see if there is room for a new leaf node */ if (node->u.kids[0]->flags.is_leaf && i < M_SIZE) { struct rtree_node *new_node; new_node = (struct rtree_node *)calloc (1, sizeof (*new_node)); new_node->parent = node; new_node->flags.is_leaf = true; node->u.kids[i] = new_node; new_node->u.rects[0].bptr = query; new_node->u.rects[0].bounds = *query; new_node->box = *query; if (UNLIKELY (manage)) new_node->flags.manage = 1; sort_node (node); return; } /* Ok, so we're still here - look for the best child to push it into */ best_score = penalty (node->u.kids[0], query); best_node = node->u.kids[0]; for (i = 1; i < M_SIZE; i++) { if (!node->u.kids[i]) break; score = penalty (node->u.kids[i], query); if (score < best_score) { best_score = score; best_node = node->u.kids[i]; } } __r_insert_node (best_node, query, manage, true); sort_node (node); return; } }
dtree_t * mk_tree(float32 ****mixw, float32 ****means, float32 ****vars, uint32 *veclen, uint32 n_model, uint32 n_state, uint32 n_stream, uint32 n_density, float32 *stwt, uint32 *id, uint32 n_id, quest_t *all_q, uint32 n_all_q, pset_t *pset, uint32 **dfeat, uint32 n_dfeat, uint32 split_min, uint32 split_max, float32 split_thr, float32 mwfloor) { dtree_t *s_tree; uint32 i; dtree_node_t *b_n, *root; s_tree = ckd_calloc(1, sizeof(dtree_t)); s_tree->node = ckd_calloc(2*split_max + 1, sizeof(dtree_node_t)); s_tree->n_node = 0; s_tree->node[0].node_id = 0; s_tree->n_node = 1; root = &s_tree->node[0]; mk_node(root, 0, id, n_id, mixw, means, vars, veclen, n_model, n_state, n_stream, n_density, stwt, mwfloor); set_best_quest(root, mixw, means, vars, veclen, n_model, n_state, n_stream, n_density, stwt, all_q, n_all_q, pset, dfeat, n_dfeat, mwfloor); if (root->q == NULL) { /* No question found that is able to split node; can't go any further */ free_tree(s_tree); return NULL; } for (i = 0; i < split_max; i++) { b_n = best_leaf_node(root); if (b_n == NULL) { E_INFO("stop. leaf nodes are specific\n"); break; } /* DDDDDBUG The following criteria will fail if we use only likelihood and no likelihood increase */ if (b_n->wt_ent_dec <= 0) { E_INFO("stop. b_n->wt_ent_dec (%.3e) <= 0\n", b_n->wt_ent_dec); break; } if ((i > split_min) && (b_n->wt_ent_dec < split_thr * b_n->wt_ent)) { E_INFO("stop. b_n->wt_ent_dec (%.3e) < split_thr * b_n->wt_ent (%.3e)\n", b_n->wt_ent_dec, b_n->wt_ent * split_thr); break; } split_node(s_tree, b_n->node_id, mixw, means, vars, veclen, n_model, n_state, n_stream, n_density, stwt, all_q, n_all_q, pset, dfeat, n_dfeat, mwfloor); } #if 1 E_INFO("Final simple tree\n"); print_tree(stderr, "|", root, pset, 0); fprintf(stderr, "\n"); #endif return s_tree; }
int compute_tree(Tree *tree,int n,int d,double *x[], int y[],int stumps,int minsize) /* compute tree model.x,y,n,d are the input data. stumps takes values 1 (compute single split) or 0 (standard tree). minsize is the minimum number of cases required to split a leaf. Return value: 0 on success, 1 otherwise. */ { int i,j; int node_class_index; int max_node_points; int cn; double sumpriors; tree->n=n; tree->d=d; if(stumps != 0 && stumps != 1){ fprintf(stderr,"compute_tree: parameter stumps must be 0 or 1\n"); return 1; } if(minsize < 0){ fprintf(stderr,"compute_tree: parameter minsize must be >= 0\n"); return 1; } tree->nclasses=iunique(y,tree->n, &(tree->classes)); if(tree->nclasses<=0){ fprintf(stderr,"compute_tree: iunique error\n"); return 1; } if(tree->nclasses==1){ fprintf(stderr,"compute_tree: only 1 class recognized\n"); return 1; } if(tree->nclasses==2) if(tree->classes[0] != -1 || tree->classes[1] != 1){ fprintf(stderr,"compute_tree: for binary classification classes must be -1,1\n"); return 1; } if(tree->nclasses>2) for(i=0;i<tree->nclasses;i++) if(tree->classes[i] != i+1){ fprintf(stderr,"compute_tree: for %d-class classification classes must be 1,...,%d\n",tree->nclasses,tree->nclasses); return 1; } if(!(tree->x=dmatrix(n,d))){ fprintf(stderr,"compute_tree: out of memory\n"); return 1; } if(!(tree->y=ivector(n))){ fprintf(stderr,"compute_tree: out of memory\n"); return 1; } for(i=0;i<n;i++){ for(j=0;j<d;j++) tree->x[i][j]=x[i][j]; tree->y[i]=y[i]; } tree->stumps = stumps; tree->minsize = minsize; tree->node=(Node *)malloc(sizeof(Node)); tree->node[0].nclasses=tree->nclasses; tree->node[0].npoints = tree->n; tree->node[0].nvar = tree->d; tree->node[0].data=tree->x; tree->node[0].classes=tree->y; tree->node[0].npoints_for_class=ivector(tree->nclasses); tree->node[0].priors=dvector(tree->nclasses); for(i=0;i<tree->node[0].npoints;i++){ for(j = 0; j < tree->nclasses;j++) if(tree->classes[j]==tree->node[0].classes[i]){ tree->node[0].npoints_for_class[j] += 1; break; } } node_class_index=0; max_node_points=0; for(j = 0; j < tree->nclasses;j++) if(tree->node[0].npoints_for_class[j] > max_node_points){ max_node_points = tree->node[0].npoints_for_class[j]; node_class_index = j; } tree->node[0].node_class = tree->classes[node_class_index]; sumpriors=.0; for(j=0;j < tree->nclasses;j++) sumpriors += tree->node[0].npoints_for_class[j]; for(j = 0; j < tree->nclasses;j++) tree->node[0].priors[j] = tree->node[0].npoints_for_class[j]/sumpriors; tree->node[0].terminal=TRUE; if(gini_index(tree->node[0].priors,tree->nclasses)>0) tree->node[0].terminal=FALSE; tree->nnodes=1; for(cn=0;cn<tree->nnodes;cn++) if(!tree->node[cn].terminal){ tree->node[cn].left=tree->nnodes; tree->node[cn].right=tree->nnodes+1; tree->node=(Node *)realloc(tree->node,(tree->nnodes+2)*sizeof(Node)); split_node(&(tree->node[cn]),&(tree->node[tree->nnodes]), &(tree->node[tree->nnodes+1]),tree->classes,tree->nclasses); if(tree->minsize>0){ if(tree->node[tree->nnodes].npoints < tree->minsize) tree->node[tree->nnodes].terminal = TRUE; if(tree->node[tree->nnodes+1].npoints < tree->minsize) tree->node[tree->nnodes+1].terminal = TRUE; } if(tree->stumps){ tree->node[tree->nnodes].terminal = TRUE; tree->node[tree->nnodes+1].terminal = TRUE; } tree->nnodes += 2; } return 0; }
void InsertNode(int data) { int flag = 0; if (head->right == head) { // Configure 'Starting Node' node *ptr = (node *)malloc(sizeof(node)); ptr->lData = data; ptr->rData = -1; ptr->left = head; ptr->mid = head; ptr->right = head; /* Configure head node -> head node to 'Start Node' */ head->left = ptr; head->mid = ptr; head->right = ptr; } else { // If not... node *tmp = head->left; parent = head; for (;;) { if (tmp->lData < data) { if (tmp->rData == -1) break; else { if (tmp->left == head) { flag = 1; break; } else { if (tmp->rData < data) { if (tmp->mid == head) break; else { parent = tmp; tmp = tmp->mid; } } else { if (tmp->mid == head) break; else { parent = tmp; tmp = tmp->mid; } } } } } else { if (tmp->left == head) { if (tmp->rData == -1) flag = 0; else flag = 1; break; } else { parent = tmp; tmp = tmp->left; } } } if (tmp->rData == -1 && flag == 0) { if (tmp->lData < data) tmp->rData = data; else { tmp->rData = tmp->lData; tmp->lData = data; } } else if (flag > 0) { /* Configure node for Inserting */ node *ptr = (node *)malloc(sizeof(node)); ptr->lData = data; ptr->rData = -1; ptr->left = head; ptr->mid = head; ptr->right = head; if (flag == 1) { parent->left = split_node(tmp, ptr); tmp = parent->left; if (parent->rData == -1) { parent->rData = parent->lData; parent->lData = tmp->lData; parent->right = parent->mid; parent->mid = tmp->mid; parent->left = tmp->left; } } } } }
/* mark with one more hit the given IP address - */ struct ip_node* mark_node(unsigned char *ip,int ip_len, struct ip_node **father,unsigned char *flag) { struct ip_node *node; struct ip_node *kid; int byte_pos; kid = root->entries[ ip[0] ].node; node = 0; byte_pos = 0; LM_DBG("search on branch %d (top=%p)\n", ip[0],kid); /* search into the ip tree the longest prefix matching the given IP */ while (kid && byte_pos<ip_len) { while (kid && kid->byte!=(unsigned char)ip[byte_pos]) { kid = kid->next; } if (kid) { node = kid; kid = kid->kids; byte_pos++; } } LM_DBG("only first %d were matched!\n",byte_pos); *flag = 0; *father = 0; /* what have we found? */ if (byte_pos==ip_len) { /* we found the entire address */ node->flags |= NODE_IPLEAF_FLAG; /* increment it, but be careful not to overflow the value */ if(node->leaf_hits[CURR_POS]<MAX_TYPE_VAL(node->leaf_hits[CURR_POS])-1) node->leaf_hits[CURR_POS]++; /* becoming red node? */ if ( (node->flags&NODE_ISRED_FLAG)==0 ) { if (is_hot_leaf(node) ) { *flag |= RED_NODE|NEWRED_NODE; node->flags |= NODE_ISRED_FLAG; } } else { *flag |= RED_NODE; } } else if (byte_pos==0) { /* we hit an empty branch in the IP tree */ assert(node==0); /* add a new node containing the start byte of the IP address */ if ( (node=new_ip_node(ip[0]))==0) return 0; node->hits[CURR_POS] = 1; node->branch = ip[0]; *flag = NEW_NODE ; /* set this node as root of the branch starting with first byte of IP*/ root->entries[ ip[0] ].node = node; } else{ /* only a non-empty prefix of the IP was found */ if ( node->hits[CURR_POS]<MAX_TYPE_VAL(node->hits[CURR_POS])-1 ) node->hits[CURR_POS]++; if ( is_hot_non_leaf(node) ) { /* we have to split the node */ *flag = NEW_NODE ; LM_DBG("splitting node %p [%d]\n",node,node->byte); *father = node; node = split_node(node,ip[byte_pos]); } else { /* to reduce memory usage, force to expire non-leaf nodes if they * have just a few hits -> basically, don't update the timer for * them the nr of hits is small */ if ( !is_warm_leaf(node) ) *flag = NO_UPDATE; } } return node; }