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

📄 btree.c

📁 btree的实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *                Larry A. Walker & Co. B+TreeR2	Corp. 1991,1995 Larry A. Walker (Larry A. Walker & Co.)	                All rights reserved.  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "treelib.h"#include "btree.h"#include "bfh.h"#include "debug.h"/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *	standard compare routines* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//*// NAME: 	pascal_string_compare//// DESCRIPTION:	The format of these strings consists of a leading byte //		which designates//		the length of the string, followed by the contents of the //		string.//		All comparison value routines must return -1, 0 or 1 as//		the result of the comparison.  Note:  The specifications for//		strncmp() do not meet this requirement.//		Here, if the length of one string is less//		than the length of another, it is automatically a value//		less than aother.//// RETURN:	-1 LT, 0 EQ, 1 GT//*/static int pascal_string_compare(union Key * value, /* A raw key */			  struct KeyGroup * active_key,/* An encapsolated key */			  int lng /* A place holder here */){	int status;	Trace("pascal_string_compare(%x, %x, %d)", (unsigned)value, (unsigned)active_key, lng);	status = strncmp((value->key)+1,(active_key->k.key)+1,		(active_key->k.key[0] > value->key[0])?			(int)active_key->k.key[0]:value->key[0] );	if(status==0)		return status;	return ( (status < 1)? -1 : 1 );}/*// NAME:	long_compare//// DESCRIPTION:	Compare two long values, returning the result//// RETURN:	-1 LT, 0 EQ, 1 GT//*/static int long_compare( union Key * value, /* A raw key */		  struct KeyGroup * active_key, /* An encapsolated key */		  int lng /* A place holder here */){	Trace("long_compare(%x, %x, %d)", (unsigned)value, (unsigned)active_key, lng);	if(value->long_key < active_key->k.long_key)		return -1;	if(value->long_key > active_key->k.long_key)		return 1;	return 0;}/*// NAME:	double_compare//// DESCRIPTION:	Compare two double values, returning the result.  	    It is possible for an archatecture to be satisified with a 32bit	    alignment and complain when a double lands on a non 64 bit 	    boundry - usually indicating a 64 bit fpu.  If everything else 	    works fine except float trees, define _64BITFPU	    example HP9000//// RETURN:	-1 LT, 0 EQ, 1 GT//*/static int double_compare( union Key * value, /* A raw key */		  struct KeyGroup * active_key, /* An encapsolated key */		  int lng /* A place holder here */){#ifdef _64BITFPU	double vd, ad;#else#define vd value->double_key#define ad active_key->k.double_key#endif	Trace("double_compare(%x, %x, %d)\n", (unsigned)value, (unsigned)active_key, lng);#ifdef _64BITFPU	memcpy((void *)&vd, (void*)&(value->double_key), sizeof(double));	memcpy((void *)&ad, (void*)&(active_key->k.double_key), sizeof(double));#endif	if(vd < ad)		return -1;	if(vd > ad)		return 1;	return 0;}/*// NAME:	fix_lng_compare//// DESCRIPTION:	Compare two fixed length values, returning the result.//// RETURN:	-1 LT, 0 EQ, 1 GT//*/static int fix_lng_compare( 	union Key * value, /* A raw key */			struct KeyGroup * active_key, /* An encapsolated key*/			int lng /* key size */ ){	int status;	Trace("fix_lng_compare(%x, %x, %d)", (unsigned)value, (unsigned)active_key, lng);	status = strncmp(value->key,active_key->k.key,lng);	if(status==0)		return status;	return ( (status < 1)? -1 : 1 );}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *	move memory* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//* //// NAME:	move memory, allowing for overlapping memory areas//// DESCRIPTION:	Slower than any assembly language counterpart that //		would replace it, but this routine has proven most//		trustworthy in any situation.//// RETURN:	NONE//*/void mv_mem(	char *source,/* memory at */		char *destin,/* memory to */		int len /* for length */ ){	Trace("mv_mem(%x, %x, %d)\n", (unsigned)source, (unsigned)destin, len);	if(len < 1)return;	if(destin < source)	{		while(len--)		{			*destin=(*source); destin++; source++;		}		return;	}	else	{		source+=(len-1); destin+=(len-1);		while(len--)		{			*destin=(*source); destin--; source--;		}		return;	}}/* 	--- Here is the alternative, if it works correctly, use it, the routine 	    since the routine would be in assembly*/#define mv_mem(s,d,l) memmove(d,s,l)/*// NAME:	create_index_string//// DESCRIPTION:	This utility will take a null terminated C string and create//		a pascal type string as required for indexing.  The first //		byte of the string provides the length of the string.  The//		length of the string is therefor limited to 255 characters.//		In actual indexing practice the it isnt reasonable to assume//		that variable length keys should be allowed to be more than//		about 64 characters.  //		If you want your index to fail, change the commented code.//		As it is, it will simply take the first MASVARSTR characters//		from the string to create the index key string.//// RETURN:	SUCCESS or FAIL//*/int create_index_string(char * to /*place the results here*/, 			char * fm /*convert this string */){	int i;	Trace("create_index_string(%x,%x)\n", (unsigned)to, (unsigned)fm);	i  = strlen(fm);	if(i > MAXVARSTR){		/*fprintf(stderr,"Warning: %s: Line %d: String too long",__FILE__, __LINE__);*/		/*return FAIL;*/		i=MAXVARSTR;	}	*to = (char)i;	mv_mem(fm,to+1,i);	return SUCCESS;}/*// NAME:	create_c_string//// DESCRIPTION:	This utility will take an index type (pascal type) string //		and create a standard null terminated C string.//// RETURN:	Always returns SUCCESS//*/int create_c_string(char * to /* put the new string here */, 		    char * fm /* get the pascal string from here */) {	int i;	Trace(" create_c_string(%x,%x)\n", (unsigned)to, (unsigned)fm);	i = (int)(*fm);	strncpy(to,++fm,i);	*(to+i) = 0;	return SUCCESS;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *	Btree class routines* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//*// NAME:	OpenKeyNode//// DESCRIPTION:	This function takes a pointer to a node and initializes//		the class instance to use it as the current active node.//		All active operations will be performed on this node.//// RETURN:	NONE//*/void OpenKeyNode(BTREE * btree, /* tree descriptor pointer */		 struct Node * n /* pointer to new active node */  ){	Trace("OpenKeyNode(%x,%x)\n", (unsigned)btree,		(unsigned)n);	btree->active_node = n;	btree->left = btree->active_node->nodeblock.left_node;	btree->key_position = 1;	btree->active_key = (struct KeyGroup *)(((char *)n) + FirstKeyOffset); }/*// NAME:	Btree//// DESCRIPTION:	Btree initialization function.  Will create a new index if//		second parameter is CREATE and index does not already exist.//		The first parameter is the name of the index.//		The third parameter is the type of key.//		If the fourth parameter is set to 1, duplicate keys will be//		allowed.  If 0 duplicates will not be allowed.//		If the keys are not variable length, the fixed key length//		size should be the fifth parameter.  For example, long keys//		would be sizeof(long).//// RETURN://*/BTREE * OpenBtree(	char *index_name, /* disk file name */			int create, /* true or false */			int tok, /* VAR_LNG_KEY or FIX_LNG_KEY or LONG_KEY or DOUBLE_KEY */			int dups, /* duplicate keys allowed, true or false */			int fix_key_size /* ignored, or size of key if fixed length */){	int i;	BTREE * btree;	Trace("OpenBtree( %s,%d,%d,%d,%d)\n", index_name, create, tok, 		dups, fix_key_size);	btree = (BTREE*)calloc( 1, sizeof(BTREE) );	if(btree == NULL){		Debug("Can't allocate space\n");		return NULL;	};	/**	--- Initialize the btree handle*/        btree->vector = -1;  /* -1 = empty*/	btree->blocks_to_flush = 0;	btree->ActiveHeight = 0;	btree->hierarchy_list = NULL;	btree->active_node = NULL;	btree->active_key = NULL;	btree->key_copy = NULL;	btree->key_position = -1;	btree->left = -1L;	btree->past_exact_key = 0;	btree->compare_funct = NULL;	btree->rootsplit=0;	btree->lock_on=0;	if(create == CREATE ){		btree->magic = 2216L;		btree->search_levels = 0;		btree->duplicates = dups;		btree->type_of_key = tok;		btree->fix_lng_key_lng = fix_key_size;		btree->rootnode = 0L;		btree->number_of_keys = 0L;		btree->exhausted = 1;		/*this will not be the same size as the bfh block_size*/		btree->block_size = TreeBlockSize;		/* override the lng parameter */		switch(tok){			case VAR_LNG_KEY:				btree->fix_lng_key_lng = -1;				break;			case LONG_KEY:				btree->fix_lng_key_lng = sizeof(long);				break;			case DOUBLE_KEY:				btree->fix_lng_key_lng = sizeof(double);				break;			case FIX_LNG_KEY:/**	--- Fix alignment problems on certain hardware (Sun)*/				if(fix_key_size)#ifdef ALIGN2				if(!((fix_key_size + 2 ) % 2) )                                	btree->fix_lng_key_lng = fix_key_size;				else                                	btree->fix_lng_key_lng = fix_key_size +                                	( 2 - ( (fix_key_size+2) % 2 ) );#endif#ifdef ALIGN4				if(!((fix_key_size + 4 ) % 4) )                                	btree->fix_lng_key_lng = fix_key_size;				else                                	btree->fix_lng_key_lng = fix_key_size +                                	( 4 - ( (fix_key_size+4) % 4 ) );#endif				break;			default:				Debug("Invalid type of key\n");				break;		}		if((btree->fix_lng_key_lng < 1) && (tok != VAR_LNG_KEY) ){			Debug("Invalid key size\n");			free ((void*)btree);			return NULL;		}		btree->bfh = BfhOpen ( index_name, btree, sizeof(BTREE), CREATE, TreeBlockSize );		if(btree == NULL){			Debug("Failed to open %s\n", index_name);			free ((void*)btree);			return NULL;		}	}else{		btree->bfh = BfhOpen ( index_name, btree, sizeof(BTREE), 0, 0);		if(btree == NULL){			Debug("Failed to open %s\n", index_name);			free ((void*)btree);			return NULL;		}		if(btree->magic != 2216L){			Debug("%s Not a btree file\n",index_name);			free ((void*)btree);			return NULL;		}	}	/* Next we need a hierarchy to store our nodes*/	btree->ActiveHeight=(MaxHierarchyPointers >= 		(btree->search_levels+2))?		MaxHierarchyPointers:btree->search_levels+2;	btree->hierarchy_list = (struct HierarchyBlock *)		calloc(btree->ActiveHeight,sizeof(struct HierarchyBlock) );	if(btree->hierarchy_list == NULL){		Debug("Failed to allocate memory.\n");		free( (void*)btree) ;		return NULL;	}	for(i=0;i<btree->ActiveHeight;i++){		(btree->hierarchy_list+i)->block_id = -1L;		(btree->hierarchy_list+i)->state = CLEAN;	}	/* Install the comparison routine*/	if(create != CREATE){		if( (tok != btree->type_of_key) && (tok != 0) ){			Debug("Invalid type of key\n");		}		tok = btree->type_of_key;	}	Trace("install tok # %d\n",tok);	switch(tok){		case VAR_LNG_KEY:			btree->compare_funct = pascal_string_compare;			break;		case LONG_KEY:			btree->compare_funct = long_compare;			break;		case DOUBLE_KEY:			btree->compare_funct = double_compare;			break;		case FIX_LNG_KEY:			btree->compare_funct = fix_lng_compare;			break;		default:			Debug("Invalid type of key\n");			break;	}	btree->time_of_last_open = time(NULL);	return btree;} /* Btree*//*// NAME:	Close//// DESCRIPTION:	Shutdown a btree.//// RETURN:	Result of the block file handler closing function//*/int Close(BTREE * btree /* pointer to tree descriptor */){	int stat;	Trace("Close(%x)\n", (unsigned)btree);	FlushHierarchy(btree);	free ((void *)btree->hierarchy_list);	if(btree->key_copy != NULL)

⌨️ 快捷键说明

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