Esempio n. 1
0
static int 
btree_delete_min(struct btree_s *tree, struct bnode_s *r)
{
	if (r->leaf) {
		int min = r->key[0], i;
		for (i = 1; i <= r->nkeys-1; i++) {
			r->key[i-1] = r->key[i];
		}
		r->nkeys--;
		return min;
	} else {
		struct bnode_s *left_most_chlid = r->child[0];
		if (left_most_chlid->nkeys >= tree->min_key_nr+1) {
			return btree_delete_min(tree, left_most_chlid);
		} else {
			struct bnode_s *right = r->child[1];
			if (right->nkeys >= tree->min_key_nr+1) {
				left_rotate(tree, r, 0);
			} else {
				merge_child(tree, r, 0);
			}
			return btree_delete_min(tree, r->child[0]);
		}

	}
}
Esempio n. 2
0
ParseNode* merge_tree(void *malloc_pool, ObItemType node_tag, ParseNode* source_tree)
{
  int index = 0;
  int num = 0;
  ParseNode* node;
  if(source_tree == NULL)
    return NULL;
  num = count_child(source_tree);
  node = new_node(malloc_pool, node_tag, num);
  merge_child(node, source_tree, &index);
  assert(index == num);
  return node;
}
Esempio n. 3
0
static int
btree_delete_max(struct btree_s *tree, struct bnode_s *r)
{
	if (r->leaf) {
		int max = r->key[r->nkeys-1];
		r->nkeys--;
		return max;
	} else {
		struct bnode_s *right_most_child = r->child[r->nkeys];
		if (right_most_child->nkeys >= tree->min_key_nr+1) {
			return btree_delete_max(tree, right_most_child);
		} else {
			struct bnode_s *left = r->child[r->nkeys-1];
			if (left->nkeys >= tree->min_key_nr+1) {
				right_rotate(tree, r, r->nkeys-1);
			} else {
				merge_child(tree, r, r->nkeys-1);
			}
			return btree_delete_max(tree, r->child[r->nkeys]);
		}
	}
}
Esempio n. 4
0
void merge_child(ParseNode* node, ParseNode* source_tree, int* index)
{
  // assert(node);
  if (node == NULL || source_tree == NULL)
    return;

  if(source_tree->type_ == T_LINK_NODE)
  {
    int i;
    for(i = 0; i < source_tree->num_child_; ++i)
    {
      merge_child(node, source_tree->children_[i], index);
      source_tree->children_[i] = 0;
    }
    destroy_tree(source_tree);
  }
  else
  {
    assert(*index >= 0 && *index < node->num_child_);
    node->children_[*index] = source_tree;
    ++(*index);
  }
}
Esempio n. 5
0
void 
btree_remove_impl(struct btree_s *tree, struct bnode_s *r, int k)
{
	int i = r->nkeys - 1;
	while (i >= 0 && k < r->key[i])
		i--;

	if (i >= 0 && k == r->key[i]) {
		/* 要删除的节点在本节点 */
		if (r->leaf) {
			/* 叶子节点,直接删除 */
			for (; i < r->nkeys; i++) {
				r->key[i] = r->key[i+1];
			}
			r->nkeys--;
		} else {
			/* 非叶子节点 */
			assert(i >= 0 && "error");
			int left = LEFT_CHILD_OF_KEY(i);
			int right = RIGHT_CHILD_OF_KEY(i);
			if (r->child[left]->nkeys >= tree->min_key_nr+1) {
				/* 左边的孩子的key足够t个 */
				r->key[i] = btree_delete_max(tree, r->child[left]);
			} else if (r->child[right]->nkeys >= tree->min_key_nr+1) {
				/* 右边的孩子的key足够t个 */
				r->key[i] = btree_delete_min(tree, r->child[right]);
			} else {
				/* 都不够,需要合并 */
				merge_child(tree, r, i);
				if (r->nkeys == 0) { 
					tree->root = r->child[0];
					release_node(r);
					btree_remove_impl(tree, tree->root, k);
				} else {
					btree_remove_impl(tree, r->child[i], k);
				}
			}
		}
	} else {
		if (i >= 0 && r->leaf) {
			printf("%d, %d, \n", i, k);
			void btree_dump(struct btree_s *);
			btree_dump(tree);
			assert(0 && "not in tree");
		}
		/* 要删除的节点不在本节点 */
		int remove_child_pos = RIGHT_CHILD_OF_KEY(i);
		if (r->child[remove_child_pos]->nkeys >= tree->min_key_nr+1) {
			/* 子节点的key个数足够t */
			btree_remove_impl(tree, r->child[remove_child_pos], k);
		} else {
			/* key个数不够 */
			if (remove_child_pos-1 >=0 && 
					r->child[remove_child_pos-1]->nkeys >= tree->min_child_nr+1) {
				/* 有左兄弟且左兄弟够 */
				right_rotate(tree, r, LEFT_KEY_OF_CHILD(remove_child_pos));
				btree_remove_impl(tree, r->child[remove_child_pos], k);
			} else if (remove_child_pos+1 <= r->nkeys &&  
					r->child[remove_child_pos+1]->nkeys >= tree->min_child_nr+1) {
				/* 有右兄弟且有兄弟够 */
				left_rotate(tree, r, RIGHT_KEY_OF_CHILD(remove_child_pos));
				btree_remove_impl(tree, r->child[remove_child_pos], k);
			} else {
				/* 都不够 */
				int merge_pos = -1; 
				if (remove_child_pos-1 >= 0) {
					merge_pos = LEFT_KEY_OF_CHILD(remove_child_pos);
				} else if (remove_child_pos+1 <= r->nkeys) {
					merge_pos = RIGHT_KEY_OF_CHILD(remove_child_pos);
				} else {
					assert(0 && "damn");
				}
				merge_child(tree, r, merge_pos);
				if (r->nkeys == 0) {
					tree->root = r->child[0];
					release_node(r);
					btree_remove_impl(tree, tree->root, k);
				} else {
					btree_remove_impl(tree, r->child[merge_pos], k);
				}
			}
		}
	}
}