Exemple #1
0
/* search in a node's child */
int _search_child(struct cursor *cur,
                  struct search *so,
                  struct node *n,
                  int childnum)
{
	int ret;
	NID child_nid;
	int child_to_search;
	struct node *child;

	nassert(n->height > 0);
	ancestors_append(cur, n->parts[childnum].msgbuf);

	child_nid = n->parts[childnum].child_nid;
	if (!cache_get_and_pin(cur->tree->cf, child_nid, (void**)&child, L_READ)) {
		__ERROR("cache get node error, nid [%" PRIu64 "]", child_nid);

		return NESS_ERR;
	}

	child_to_search = _search_in_which_child(so, child);
	ret = _search_node(cur, so, child, child_to_search);

	/* unpin */
	cache_unpin(cur->tree->cf, child->cpair);

	return ret;
}
GsTreeNode *GsTreeBase::insert ( GsTreeNode *key )
 {
   int cmp = _search_node ( key );

   if ( _cur!=NIL )
    { if ( cmp>0 ) // key>_cur
       { // if (_cur->right) REPORT_ERROR;
         _cur->right = key;
         key->parent = _cur;
         _rebalance ( key );
         _root->color = GsTreeNode::Black;
         _elements++;
         return key;
       }
      else if ( cmp<0 ) // key<_cur
       { // if (_cur->left) REPORT_ERROR
         _cur->left = key;
         key->parent = _cur;
         _rebalance ( key );
         _root->color = GsTreeNode::Black;
         _elements++;
         return key;
       }
      else return 0; // not inserted, already in the tree
    }
   else // tree empty
    { _root = key;
      _root->init ();
      _root->color = GsTreeNode::Black;
      _elements++;
      return key;
    }
 }
Exemple #3
0
/*
 *			|key44, key88|
 *			/		\
 *		  |key10, key20|	|key90|
 *	       /	|	 \	      \
 * |basement0|	   |basement1| |basement2|    |basement3|
 *
 *		      (a tree with height 2)
 *
 * cursor search is very similar to depth-first-search algorithm.
 * for cursor_seektofirst operation, the root-to-leaf path is:
 * key44 -> key10 -> basement0
 * and do the inner sliding along with the basement.
 * if we get the end of one leaf, CURSOR_EOF will be returned to upper on,
 * and we also set search->pivot_bound = key10, for the next time,
 * the root-to-leaf path(restart with a jump) will be:
 * key44 -> key10 -> basement1
 */
void _tree_search(struct cursor *cur, struct search *so)
{
	int r;
	NID root_nid;
	int child_to_search;
	struct tree *t;
	struct node *root;
	struct cache_operations *c_op = cur->tree->cache->c_op;

	t = cur->tree;

try_again:
	root_nid = t->hdr->root_nid;
	if (c_op->cache_get_and_pin(t->cache,
				root_nid,
				&root,
				L_READ) < 0) {
		__ERROR("cache get root node error, nid [%" PRIu64 "]",
				root_nid);

		return;
	}

	child_to_search = _search_in_which_child(so, root);
	r = _search_node(cur,
			so,
			root,
			child_to_search);

	/* unpin */
	c_op->cache_unpin_readonly(t->cache, root);

	switch (r) {
	case CURSOR_CONTINUE:
		break;
	case CURSOR_TRY_AGAIN:
		goto try_again;
		break;
	case CURSOR_EOF:
		break;
	default: break;
	}
}
Exemple #4
0
/* search in a node's child */
int _search_child(struct cursor *cur,
		struct search *so,
		struct node *n,
		int childnum)
{
	int ret;
	int child_to_search;
	NID child_nid;
	struct node *child;
	struct cache_operations *c_op = cur->tree->cache->c_op;

	nassert(n->height > 0);
	/* add basement to ances */
	ancestors_append(cur, n->u.n.parts[childnum].buffer);

	child_nid = n->u.n.parts[childnum].child_nid;
	if (c_op->cache_get_and_pin(cur->tree->cache,
				child_nid,
				&child,
				L_READ) < 0) {
		__ERROR("cache get node error, nid [%" PRIu64 "]",
				child_nid);

		return NESS_ERR;
	}

	child_to_search = _search_in_which_child(so, child);
	ret = _search_node(cur,
			so,
			child,
			child_to_search);

	/* unpin */
	c_op->cache_unpin_readonly(cur->tree->cache, child);

	return ret;
}
Exemple #5
0
/*
 *			|key44, key88|
 *			/		\
 *		  |key10, key20|	|key90|
 *	       /	|	 \	      \
 * |msgbuf0|	   |msgbuf1| |msgbuf2|    |msgbuf3|
 *
 *		      (a tree with height 2)
 *
 * cursor search is very similar to depth-first-search algorithm.
 * for cursor_seektofirst operation, the root-to-leaf path is:
 * key44 -> key10 -> msgbuf0
 * and do the inner sliding along with the msgbuf.
 * if we get the end of one leaf, CURSOR_EOF will be returned to upper on,
 * and we also set search->pivot_bound = key10, for the next time,
 * the root-to-leaf path(restart with a jump) will be:
 * key44 -> key10 -> msgbuf1
 */
void _tree_search(struct cursor * cur, struct search * so)
{
	int r;
	NID root_nid;
	int child_to_search;
	struct buftree *t;
	struct node *root;

	t = cur->tree;

TRY_AGAIN:
	root_nid = t->hdr->root_nid;
	if (!cache_get_and_pin(t->cf, root_nid, (void**)&root, L_READ)) {
		__ERROR("cache get root node error, nid [%" PRIu64 "]", root_nid);

		return;
	}

	child_to_search = _search_in_which_child(so, root);
	r = _search_node(cur, so, root, child_to_search);

	/* unpin */
	cache_unpin(t->cf, root->cpair);

	switch (r) {
	case CURSOR_CONTINUE:	  /* got the end of leaf */
		goto TRY_AGAIN;
		break;
	case CURSOR_TRY_AGAIN:	  /* got the end of node */
		goto TRY_AGAIN;
		break;
	case CURSOR_EOF:
		break;
	default:
		break;
	}
}
bool GsTreeBase::search_and_remove ( const GsTreeNode* key )
 {
   int cmp = _search_node ( key );
   if ( cmp==0 ) { remove ( _cur ); return true; }
   return false;
 }
GsTreeNode* GsTreeBase::search_and_extract ( const GsTreeNode* key )
 {
   int cmp = _search_node ( key );
   if ( cmp!=0 ) return 0; // not found
   return extract ( _cur );
 }
GsTreeNode *GsTreeBase::search ( const GsTreeNode *key )
 {
   if ( _root==NIL ) return 0;
   return _search_node(key)==0? _cur:0;
 }