Exemple #1
0
 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;
         }
     }
 }
Exemple #2
0
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);
	}
}
Exemple #3
0
//{{{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);
}
Exemple #4
0
/* 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;
}
Exemple #5
0
// 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);	
	}
}
Exemple #6
0
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;
    }
}
Exemple #7
0
// 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;
}
Exemple #8
0
//插入到一个非空节点
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);
	}
}
Exemple #9
0
//{{{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]);

}
Exemple #10
0
/*!
 * \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;
		}
	}
}
Exemple #12
0
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);
	}
}
Exemple #13
0
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);
        }
    }
}
Exemple #14
0
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);
}
Exemple #15
0
/*
 * 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;
}
Exemple #16
0
/*
 * 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;
}
Exemple #17
0
 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);
     }
 }
Exemple #18
0
// ------------------------------------------------------------------------
// 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));
}
Exemple #19
0
	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);
		}
	}
Exemple #20
0
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;
    }
}
Exemple #21
0
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;
}
Exemple #22
0
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;
  
}
Exemple #23
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;
				}
			}
		}
	}
}
Exemple #24
0
/* 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;
}