⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btree.c

📁 btree的实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
// RETURN:	SUCCESS or FAIL//*/int  DeleteKey (BTREE * btree /* pointer to tree descriptor */,	        union Key * delete_key /* An encapsolated key */){	Trace("DeleteKey (%x,%x)\n", (unsigned)btree, (unsigned)delete_key);	if( btree->exhausted)		return FAIL;	/* we could have eof success fail or near match */	if(LocateExact(btree,delete_key) != SUCCESS){		Debug("Couldnt locate key\n");		return FAIL;	}	/* check for leaf*/	/* delete it and call combine*/	if( btree->active_key->right_node == -1L){		if(DeleteNodeKeyGroup(btree) == SUCCESS){			btree->number_of_keys--;			if(btree->number_of_keys == 0){				btree->exhausted = 1;				btree->search_levels = 0;                		if(BfhFreeBlock(btree->bfh, btree->rootnode ) 						== FAIL){		                        Debug("Cant free block\n");               		         	return FAIL;                		}				btree->hierarchy_list->state = CLEAN;			}else{				if(btree->vector > 0)					CombineAll(btree);			}			FlushHierarchy(btree);			return SUCCESS;		} else {			Debug("Couldnt delete\n");			return FAIL;		}	}	/* ----  must be interior node*/	if(RemoveNodeKeyGroup(btree) != SUCCESS){		Debug("Coundnt remove the key\n");		return FAIL;	}	btree->number_of_keys--;	FlushHierarchy(btree);	return SUCCESS;} /* operator -=*//*// NAME:    CombineAll//// DESCRIPTION:  Calls the Combine() routine from the current vector until the//              root has been reached//// RETURN:     Pointer the the first key group in the tree, or NULL on//              failure.//*/static void CombineAll(BTREE * btree/* pointer to tree descriptor */){        int status;	int current;	Trace("CombineAll(%x)\n", (unsigned)btree);	current = btree->vector;        while(1){                status = Combine(btree);                if(status == FAIL)                        break;		btree->vector = current;                btree->vector --; current --;                if( !btree->vector )                        break;                OpenKeyNode( btree,&(btree->hierarchy_list+btree->vector)->hierarchy_node);        }} /* end CombineAll()*//*// NAME:	First//// DESCRIPTION:	Locate and return a pointer to the first key group in the//		tree.//// RETURN:	Pointer the the first key group in the tree, or NULL on //		failure.//*/struct KeyGroup * First(BTREE * btree /* pointer to tree descriptor */){	long next_node;	Trace("First(%x)\n", (unsigned)btree);	if(btree->exhausted)		return FAIL;	next_node = btree->rootnode; /* root node */	FlushHierarchy(btree);	btree->vector = -1;	btree->active_key = NULL;	while(1){		if(LoadHierarchyNode(btree, next_node ) == FAIL){ 			Debug("Cant load node\n");			return NULL;		}		if(btree->left == -1L){			if(btree->active_node->total_node_keys == 0)				return NULL;			return (btree->active_key);			}		next_node = btree->left;	}} /* First*//*// NAME:	Increment//// DESCRIPTION:	Increment the internal pointers to the next key in the //		tree.	//// RETURN:	Pointer to next key group structure in the tree.  //		NULL on failure//*/struct KeyGroup *  Increment(BTREE * btree /* pointer to tree descriptor */){	long bid;	Trace("Increment(%x)\n",(unsigned)btree);	if (btree->exhausted )		return FAIL;	if (btree->active_key == NULL)		return NULL;	if ((btree->vector == 0) && ( btree->active_node->total_node_keys == 0 )){		/* a root node can be fully exhausted*/		btree->active_key = NULL;		return NULL;        }	/* if there is anything here we have to go south*/	if(btree->active_key->right_node != -1L){		/* decend into that group*/		if(LoadHierarchyNode(btree,btree->active_key->right_node)==SUCCESS){			/* find the lowest key down that side*/			while(btree->left != -1L){				if(LoadHierarchyNode(btree,btree->left)!=SUCCESS){					Debug("Cant load node\n");					return NULL;				}			}			return (btree->active_key);		} else { 			Debug("Cant load node\n");			return NULL;			}	}	/* otherwise lets try the next key*/	if (btree->key_position < btree->active_node->total_node_keys){		if(IncrementPosition(btree)==SUCCESS)			return (btree->active_key);		else { 			Debug("Couldnt increment\n");			return NULL;			}	}	/* if already on the last key*/	else {		int stat;		do	{			/* keep the id of the present node*/			bid = (btree->hierarchy_list+btree->vector)->block_id;			if(Parent(btree)==NULL){				Debug("Cant find parent\n");				return NULL;			}			/* look for the key that has our child*/			while(btree->left != bid){				if((stat=IncrementPosition(btree))==FAIL){					Debug("Cant increment\n");					return NULL;				}			} 			/* if we have a valid position return key*/			if(btree->key_position < ( btree->active_node->total_node_keys + 1) ){				return (btree->active_key);				}			/* if we are at eof we try again or quit if we have*/			/* run out*/		}while (btree->vector > 0);		Debug(NULL);		return NULL;	}} /* operator ++*//*// NAME:	Last//// DESCRIPTION:	Find the last key in the tree.//// RETURN:	Pointer to last key group structure in the tree.  //		NULL on failure//*/struct KeyGroup *  Last(BTREE * btree /* pointer to tree descriptor */){	long next_node;	int i;	next_node = btree->rootnode; /* root node */	Trace("Last(%x)\n", (unsigned)btree);	if(btree->exhausted)		return FAIL;	FlushHierarchy(btree);	btree->vector = -1;	while(1){		if(LoadHierarchyNode(btree, next_node ) == FAIL){ 			Debug("Couldnt load node\n");			return NULL;		}		if(btree->active_node->total_node_keys == 0)			return NULL;		/* get the rightmost key*/		for(i = 0; i < btree->active_node->total_node_keys-1;i++){			if(IncrementPosition(btree)!=SUCCESS)				return NULL;		}		if(btree->active_key->right_node == -1L){			return (btree->active_key);			}		next_node = btree->active_key->right_node;	}} /* Last*//*// NAME:	Decrement//// DESCRIPTION:	Decrement the internal pointers to the next key in the //		tree.	//// RETURN:	Pointer to previous key group structure in the tree.  //		NULL on failure*/struct KeyGroup *  Decrement (BTREE * btree /* pointer to tree descriptor */){	long bid;	int i,hold_posn;	Trace("Decrement(%x)\n", (unsigned)btree);	if(btree->exhausted)		return FAIL;	/* if there is anything here we have to go south*/        if(btree->active_key == NULL)		return NULL;	if(btree->left != -1L){		/* decend into that group*/		if(LoadHierarchyNode(btree,btree->left)==SUCCESS){			/* find the highest key down that side*/			while(1){				for(i = 0; i < btree->active_node->total_node_keys-1;						i++){					if(IncrementPosition(btree)!=SUCCESS)						return NULL;				}				if(btree->active_key->right_node == -1L)					return (btree->active_key);				if(LoadHierarchyNode(btree,btree->active_key->right_node)!=						SUCCESS){					Debug("Couldnt load node\n");					return NULL;				}			}		} else {			return NULL;		}	}	/* otherwise get prev key in same node*/	hold_posn = btree->key_position;	if(hold_posn == 1){		if(btree->vector == 0)			return NULL; /* no previous keys*/		while(1){			bid = (btree->hierarchy_list+btree->vector)->block_id;			if(Parent(btree)==NULL){				Debug("Couldnt locate parent\n");				return NULL;			}			if(btree->left == bid){				if(btree->vector == 0)					return NULL;				continue;			}			else break;		}		for(i=0;i<btree->active_node->total_node_keys;i++){			if(btree->active_key->right_node == bid)				return (btree->active_key);			if(IncrementPosition(btree)!=SUCCESS){				Debug("Couldnt increment\n");				return NULL;			}		}		return NULL;	}	Rewind(btree);	for(i=1; i < (hold_posn - 1); i++){		if(IncrementPosition(btree)!=SUCCESS){			Debug("Couldnt increment\n");			return NULL;		}	}	return (btree->active_key);}/*// NAME:	CurrentKey//// DESCRIPTION:	Identify the current key.//// RETURN:	Returns a pointer to the key group which is designated //		as the active key*/struct KeyGroup *  CurrentKey(BTREE * btree /* pointer to tree descriptor */){	Trace("CurrentKey(%x)\n", (unsigned)btree);	if(btree->exhausted)		return FAIL;	if(btree->active_key == NULL) 		return NULL;	/* exhausted root node*/	if ((btree->vector == 0) && ( btree->active_node->total_node_keys == 0 )){		/* a root node can be fully exhausted*/		return NULL;        }	else return (btree->active_key);} /* CurrentKey*//*// NAME:	Update//// DESCRIPTION:	Update the data of the current key//// RETURN:	Overwrites the key data or the address stored in a key*/int  Update(BTREE * btree /* pointer to tree descriptor */, 	    void * new_data /* new key data, consistent in type to data being replaced */){	Trace("Update(%x, %x)\n", (unsigned)btree, (unsigned)new_data);	if(btree->exhausted)		return FAIL;	if(btree->active_key == NULL) 		return FAIL;	mv_mem((char *)new_data, btree->active_key->KeyData.key_data,			USRDATASIZE /* normally sizeof(long)*/ );	(btree->hierarchy_list+btree->vector)->state = DIRTY;	return SUCCESS;} /* Update*//*// NAME:	FlushHierarchy//// DESCRIPTION:	The hierarchy leading to a node is held in a vector of //		nodes beginning with the root node and ending with the//		active node.  Nodes that have been modified are marked//		in the hierarchy as "dirty".  When a new node is being//		listed into the hierarchy, it may overlay a node already//		listed in the node.  The underlying node is written back//		to disk before the new node overwrites.  This function//		walks the hierarchy, writes dirty nodes to disk and //		marking them clean.//// RETURN:	SUCCESS or FAIL//*/int FlushHierarchy(BTREE * btree /* pointer to tree descriptor */)  {/* *** Although left as though it is completely empty, the loaded *//* *** nodes are still there, and will be reused by load routines*//* *** later as required.*/	int position, doexchange;	long exchange_addr;	long child;	Trace("FlushHierarchy(%x)\n", (unsigned)btree);	for(position = 0; position < btree->blocks_to_flush ; position++){#ifdef COMPRESS/* this routine will compress the tree into the lowest addressed blocks*/		if( (position + 1) < btree->blocks_to_flush){			child = (btree->hierarchy_list+(position+1))->block_id;			/* look for the child*/			if( ( btree->bfh->first_free_block_addr != -1L )&&				( child > btree->bfh->first_free_block_addr)) {		                OpenKeyNode(btree,&(btree->hierarchy_list+position)->hierarchy_node);				doexchange = 0;				if( btree->left == child ){					exchange_addr = BfhNewBlock(btree->bfh);					btree->active_node->nodeblock.left_node = exchange_addr;					doexchange=1;				}else{					do{					    if(btree->active_key->right_node == child){						    exchange_addr = BfhNewBlock(btree->bfh);					    	    btree->active_key->right_node = exchange_addr;						    doexchange=1;						    break;					    }					}while(IncrementPosition(btree)==SUCCESS);				}				if(doexchange){					(btree->hierarchy_list+position)->state = DIRTY;					BfhFreeBlock(btree->bfh,(btree->hierarchy_list+(position+1))->block_id);					(btree->hierarchy_list+(position+1))->block_id = exchange_addr;					(btree->hierarchy_list+(position+1))->state = DIRTY;				}			}		}#endif		if((btree->hierarchy_list+position)->state == DIRTY){                        if(BfhWriteBlock(btree->bfh, (char *)&((btree->hierarchy_list+position)->hierarchy_node),(btree->hierarchy_list+position)->block_id) == SUCCESS){				(btree->hierarchy_list+position)->state = CLEAN;			}			else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -