示例#1
0
int rbt_search(rbt r, char *s) {
   if (r == NULL) {
      return 0;
   } else if (strcmp(s, r->key) == 0) {
      return 1;
   } else if (strcmp(s, r->key) < 0) {
      return rbt_search(r->left, s);
   } else {
      return rbt_search(r->right, s); 
   }
}
示例#2
0
文件: rbt.c 项目: lchish/cosc
int rbt_search(rbt r, char *s)
{
  if(r == NULL){
    return 0;/*not found*/
  }else if(strcmp(r->key,s) == 0){
    return 1;/*found*/
  }else if(strcmp(r->key,s) < 0){/* r->key > s */
    return rbt_search(r->left,s);
  }else{/* r->key < s*/
    return rbt_search(r->right,s);
  }
}
示例#3
0
/************************************************************************
Merge the node from dst into src. Return the number of nodes merged.
@return	no. of recs merged */
UNIV_INTERN
ulint
rbt_merge_uniq(
/*===========*/
	ib_rbt_t*	dst,			/*!< in: dst rb tree */
	const ib_rbt_t*	src)			/*!< in: src rb tree */
{
	ib_rbt_bound_t		parent;
	ulint			n_merged = 0;
	const	ib_rbt_node_t*	src_node = rbt_first(src);

	if (rbt_empty(src) || dst == src) {
		return(0);
	}

	for (/* No op */; src_node; src_node = rbt_next(src, src_node)) {

		if (rbt_search(dst, &parent, src_node->value) != 0) {
			rbt_add_node(dst, &parent, src_node->value);
			++n_merged;
		}
	}

	return(n_merged);
}
static Block_t *
aoff_get_free_block(Allctr_t *allctr, Uint size,
		    Block_t *cand_blk, Uint cand_size)
{
    AOFFAllctr_t *alc = (AOFFAllctr_t *) allctr;
    AOFF_RBTree_t *crr_node = alc->mbc_root;
    AOFF_Carrier_t* crr;
    AOFF_RBTree_t *blk = NULL;
#ifdef HARD_DEBUG
    AOFF_RBTree_t* dbg_blk;
#endif
    
    ASSERT(!cand_blk || cand_size >= size);

    /* Get first-fit carrier
     */
    if (!crr_node || !(blk=rbt_search(crr_node, size))) {
	return NULL;
    }
    crr = RBT_NODE_TO_MBC(blk);

    /* Get block within carrier tree
     */
#ifdef HARD_DEBUG
    dbg_blk = HARD_CHECK_TREE(&crr->crr, alc->blk_order, crr->root, size);
#endif

    blk = rbt_search(crr->root, size);
    ASSERT(blk);

#ifdef HARD_DEBUG
    ASSERT(blk == dbg_blk);
#endif

    if (!blk)
	return NULL;

    if (cand_blk && cmp_cand_blk(alc->blk_order, cand_blk, blk) < 0) {
	return NULL; /* cand_blk was better */
    }

    aoff_unlink_free_block(allctr, (Block_t *) blk);

    return (Block_t *) blk;
}
Carrier_t* aoff_lookup_pooled_mbc(Allctr_t* allctr, Uint size)
{
    AOFF_RBTree_t* node;

    if (!allctr->cpool.pooled_tree)
	return NULL;
    node = rbt_search(allctr->cpool.pooled_tree, size);
    return node ? ErtsContainerStruct(node, Carrier_t, cpool.pooled) : NULL;
}
示例#6
0
Bool rbtsimple_create_node( /*@in@*/ RBT_ROOT *root , uintptr_t key )
{
  RBT_NODE *node = rbt_search( root , key ) ;

  if ( node == NULL ) {
    node = rbt_allocate_node( root , key , NULL ) ;

    if ( node == NULL ) {
      return FALSE ;
    }

    rbt_insert( root , node ) ;
  }

  return TRUE ;
}
示例#7
0
int PushCache(INT h, int hash, int width, int height, int format, unsigned char * data)
{
	LPCACHE_NODE pNode;
	LPCACHE_HANDLE handle = (LPCACHE_HANDLE)h;
	int ret = 0;
	if (handle == GNull) {
		return -1;
	}

	// search in rb-tree
	pNode = rbt_search(&handle->mRBRoot, hash);

	if (handle->mCurCount >= handle->mMaxCount && pNode == GNull) {
		// replace
		container_of(pNode, dl_last(&(handle->mDLRoot)), CACHE_NODE, mDLNode);
#if defined( _DEBUG )
		LOGI("replace get last 0x%X\n", pNode);
#endif
	}

	if (pNode != GNull) {
		//remove out in linked queue.
		dl_remove_node(&(pNode->mDLNode), &(handle->mDLRoot));

		//remove from rb-tree.
		rb_erase(&pNode->mRBNode, &handle->mRBRoot);

		pNode->mKey = hash;
		
	} else {
		pNode = (LPCACHE_NODE)GMemMalloc(sizeof(CACHE_NODE));
		pNode->mKey = hash;
		handle->mCurCount++;
		cache_data_initial(&(pNode->mData));
	}

	cache_data_update(&(pNode->mData), width, height, format, data);

	//add node
	dl_insert_node(&(pNode->mDLNode), GNull, &(handle->mDLRoot));

	//add to rb-tree
	rb_init_node(&pNode->mRBNode);
	rbt_insert(&handle->mRBRoot, pNode);
	return ret;
}
示例#8
0
int PullCache(INT h, int hash, int *width, int *height, int *format, unsigned char ** data)
{
	LPCACHE_NODE pNode;
	LPCACHE_HANDLE handle = (LPCACHE_HANDLE)h;
	int ret = 0;
	if (handle == GNull) {
		return PARAM_INVALID;
	}

	// search in rb-tree
	pNode = rbt_search(&handle->mRBRoot, hash);

	if (pNode != GNull) {
		//remove out.
		dl_remove_node(&(pNode->mDLNode), &(handle->mDLRoot));

		//add node
		dl_insert_node(&(pNode->mDLNode), GNull, &(handle->mDLRoot));

		cache_data_parse(&(pNode->mData), width, height, format, data);

	} else {
		//not found.
#if defined( _DEBUG )
		LPRB_NODE node;
		LPDLL_NODE link;
		LPCACHE_NODE data;
		LOGI("not found %ld\n", hash);
		for (node = rb_first(&(handle->mRBRoot)); node != GNull; node = rb_next(node)) {
			container_of(data, node, CACHE_NODE, mRBNode);
			LOGI("%ld\n", data->mKey);
		}
		LOGI("double link list:\n");
		for (link = dll_first(&(handle->mDLLRoot)); link != GNull; link = dll_next(link)) {
			container_of(data, link, CACHE_NODE, mDLLNode);
			LOGI("%ld\n", data->mKey);
		}

#endif
		return -1;
	}

	return ret;
}
示例#9
0
int QueryCache(INT h, int hash, int *width, int *height, int *format)
{
	LPCACHE_NODE pNode;
	LPCACHE_HANDLE handle = (LPCACHE_HANDLE)h;
	int ret = 0;
	if (handle == GNull) {
		return PARAM_INVALID;
	}

	// search in rb-tree
	pNode = rbt_search(&handle->mRBRoot, hash);

	if (pNode != GNull) {
		cache_data_parse(&(pNode->mData), width, height, format, GNull);
		return GOK;
	}

	return NOT_FIND;
}
示例#10
0
int main(){
    Rbt_tree_link a = rbt_create();
    Rbtlink it;
    srand(time(NULL));

    puts("Inserting...");
    for(i=0;i<N;i++) {
	num[i] = rand() % N;
	rbt_insert(a,num[i]);
    }
    
    printf("rbt_size: %d\n",rbt_size(a));

    printf("min value:%d   max value:%d\n",rbt_item(rbt_minimum(a)),rbt_item(rbt_maximum(a)));
    puts("Doing assert...");
    rbt_assert(a);
    puts("Traversing (inorder)...");
    rbt_inorder(a,func);

    for(i=0; i < N; i++)
	rbt_search(a, i);

    puts("Traversing (from max to min)...");
    it = rbt_maximum(a);
    for(i = rbt_size(a)-1; i >= 0; i--) {
	assert(n[i] == rbt_item(it));
	it = rbt_predecessor(it);
    }

    printf("rbt_size: %d\n",rbt_size(a));

    puts("Deleting all values...");
    int i = 0;
    for (i = 0; i < N; ++i) {
	printf("%d deleted\r", num[i]);
	rbt_delete(a, num[i]);
    }

    puts("\nDestroying rbt..");
    rbt_destroy(a);
    puts("OK!");
    return 0;
}
示例#11
0
/************************************************************************
Merge the node from dst into src. Return the number of nodes merged.
Delete the nodes from src after copying node to dst. As a side effect
the duplicates will be left untouched in the src.
@return	no. of recs merged */
UNIV_INTERN
ulint
rbt_merge_uniq_destructive(
/*=======================*/
	ib_rbt_t*	dst,			/*!< in: dst rb tree */
	ib_rbt_t*	src)			/*!< in: src rb tree */
{
	ib_rbt_bound_t	parent;
	ib_rbt_node_t*	src_node;
	ulint		old_size = rbt_size(dst);

	if (rbt_empty(src) || dst == src) {
		return(0);
	}

	for (src_node = (ib_rbt_node_t*) rbt_first(src); src_node; /* */) {
		ib_rbt_node_t*	prev = src_node;

		src_node = (ib_rbt_node_t*)rbt_next(src, prev);

		/* Skip duplicates. */
		if (rbt_search(dst, &parent, prev->value) != 0) {

			/* Remove and reset the node but preserve
			the node (data) value. */
			rbt_remove_node_and_rebalance(src, prev);

			/* The nil should be taken from the dst tree. */
			prev->parent = prev->left = prev->right = dst->nil;
			rbt_tree_add_child(dst, &parent, prev);
			rbt_balance_tree(dst, prev);

			++dst->n_nodes;
		}
	}

#if	defined(IB_RBT_TESTING)
	ut_a(rbt_validate(dst));
	ut_a(rbt_validate(src));
#endif
	return(rbt_size(dst) - old_size);
}
int main()
{
  // 测试方法:
  // 插入10个元素,遍历该元素,打印
  int i;
  prbtree root;
  nil =(prbtree)malloc(sizeof(rbtree));
  nil->color = BLACK;
  root = nil;
  int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  int length = sizeof(array)/sizeof(int);
  /* srand(GetTickCount()); */
  randomize_in_place(array, length);  
  print_array(array, length);  
  fflush(stdout);
  for (i = 0; i < length; i++)
    {
      prbtree y = (prbtree)malloc(sizeof(rbt_node));
      construct_node(y, array[i]);
      // print_node(y);
      root = rbt_insert_node(root, y);
      printf ("the %dth iteration\n",i + 1);
      mid_traverse_node(root);
      /* print_node(root); */
      /* printf("%x\n", (unsigned int)root); */
    }
  // mid_traverse_node(root);
  // 测试删除操作
  randomize_in_place(array, length);
  print_array(array, length);
  fflush(stdout);
  for (i = 0; i < length; ++i)
  {
       prbt_node x = rbt_search(root, array[i]);
       root = rbt_delete_node(root, x);
       printf ("the number %d deleted\n",array[i]);
       printf ("the %dth iteration\n",i + 1);
       mid_traverse_node(root);
  }
  return 0;
}
UWord
erts_aoffalc_test(UWord op, UWord a1, UWord a2)
{
    switch (op) {
    case 0x500: return (UWord) ((AOFFAllctr_t *) a1)->blk_order == FF_AOBF;
    case 0x501: {
	AOFF_RBTree_t *node = ((AOFFAllctr_t *) a1)->mbc_root; 
	Uint size = (Uint) a2;
	node = node ? rbt_search(node, size) : NULL;
	return (UWord) (node ? RBT_NODE_TO_MBC(node)->root : NULL);
    }
    case 0x502:	return (UWord) ((AOFF_RBTree_t *) a1)->parent;
    case 0x503:	return (UWord) ((AOFF_RBTree_t *) a1)->left;
    case 0x504:	return (UWord) ((AOFF_RBTree_t *) a1)->right;
    case 0x505:	return (UWord) LIST_NEXT(a1);
    case 0x506:	return (UWord) IS_BLACK((AOFF_RBTree_t *) a1);
    case 0x507:	return (UWord) IS_TREE_NODE((AOFF_RBTree_t *) a1);
    case 0x508: return (UWord) 0; /* IS_BF_ALGO */
    case 0x509: return (UWord) ((AOFF_RBTree_t *) a1)->max_sz;
    case 0x50a: return (UWord) ((AOFFAllctr_t *) a1)->blk_order == FF_BF;
    case 0x50b:	return (UWord) LIST_PREV(a1);
    default:	ASSERT(0); return ~((UWord) 0);
    }
}
示例#14
0
/* To extend the given exiting allocated block such that it can accommodate
 * at least new_sz bytes.
 */
int
extend_alloc_block(page_idx_t block_idx, size_t new_sz) {
    rb_tree_t* rbt = &alloc_info->alloc_blks;
    intptr_t alloc_sz;
    int res = rbt_search(rbt, block_idx, &alloc_sz);
#ifdef DEBUG
    ASSERT(res);
#else
    (void)res;
#endif

    int page_sz = alloc_info->page_size;
    int page_sz_log2 = alloc_info->page_size_log2;
    int min_page_num = (new_sz + page_sz - 1) >> page_sz_log2;

    page_id_t blk_id = page_idx_to_id(block_idx);
    int order = alloc_info->page_info[block_idx].order;

    /* step 1: The in-place block extension is done by merging its *following*
     *  free buddy to a form bigger block. The extension process repeats until
     *  we find a block bigger enough to accommodate the <new_sz> bytes.
     */
    int succ = 0;
    int ord;
    for (ord = order; ord <= alloc_info->max_order; ord++) {
        if (min_page_num <= (1 << ord)) {
            succ = 1;
            break;
        }

        page_id_t buddy_id = blk_id ^ (1 << ord);
        if (buddy_id < blk_id) {
            /* The buddy block must reside at higher address. */
            break;
        }

        int buddy_idx = page_id_to_idx(buddy_id);
        if (!rbt_search(&alloc_info->free_blks[ord], buddy_idx, NULL)) {
            /* bail out if the buddy is not available */
            break;
        }
    }

    /* This function is not supposed to shrink the existing block; therefore,
     * if the existing block is big enough to accommodate allocation request,
     * it need to return 0 to inform the caller that something fishy is
     * happening.
     */
    if (!succ || ord == order)
        return 0;

    /* Step 2: The previous step is merely a 'dry-run' of extension. This
     *  step is to perform real transformation.
     */
    int t;
    for (t = order; t < ord; t++) {
        page_id_t buddy_id = blk_id ^ (1 << t);
        int buddy_idx = page_id_to_idx(buddy_id);
        remove_free_block(buddy_idx, t, 0);
        reset_page_leader(alloc_info->page_info + buddy_idx);
    }

    migrade_alloc_block(block_idx, order, ord, new_sz);

    return 1;
}