#ifndef __BStreeh
#define __BStreeh
/* routines for managing B-tree data structures */
/* Note, if __TREE_RETURN is specified, then our error handling */
/* routines will be CHKERRN and MY_SETERRN, otherwise, they will be */
/* CHKERR and MY_SETERR */
#define MAX_KIDS 9
#define MAX_KEYS (MAX_KIDS-1)
#define MIN_KIDS ((MAX_KIDS+1)/2)
#define MIN_KEYS (MIN_KIDS-1)
typedef struct __BStree_node {
int num_keys;
int keys[MAX_KEYS];
char *data_ptr[MAX_KEYS];
struct __BStree_node *child[MAX_KIDS], *parent;
} BStree_node;
typedef struct __BStree_ptr {
BStree_node *ptr;
int ind;
} BStree_ptr;
/* used in the special memory management routines */
typedef struct __BSMBlock {
int base_size;
int num_units;
double *top, *bottom; /* bounds of memory for this block */
/* used for free'ing quickly */
struct __BSMBlock *next; /* Pointer to next BSMBlock */
double *free_blocks;
int num_allocated;
double v; /* Dummy for top */
} BSMBlock;
typedef struct __BStree {
BStree_node *root;
int u_data_size;
BSMBlock *node_blocks;
BSMBlock *user_blocks;
} BStree;
/* ********************** */
/* special memory section */
/* ********************** */
/* on the Intel DELTA, the memory allocation routines *can* be be quite slow */
/* thus, we have an option of using our own memory allocation routines that */
/* were adopted from those in petsc */
#if defined(PARCH_intelnx)
#define __SLOW_MALLOC
#endif
#if defined(__SLOW_MALLOC)
BSMBlock *BSsbinit(long,int);
double *BSsbmalloc();
void BSsbfree();
void BSmem_clean();
#endif
#if defined(__SLOW_MALLOC)
#if defined (__TREE_RETURN)
#define MY_MALLOC_USER_DATA(tree,data_ptr) \
{ \
if (tree.u_data_size > 0) { \
if ((data_ptr = (char *) BSsbmalloc(&(tree.user_blocks))) == NULL) { \
MY_SETERRCN(MEM_ERROR,"Out of memory allocating user data\n"); \
} \
} \
}
#else
#define MY_MALLOC_USER_DATA(tree,data_ptr) \
{ \
if (tree.u_data_size > 0) { \
if ((data_ptr = (char *) BSsbmalloc(&(tree.user_blocks))) == NULL) { \
MY_SETERRCN(MEM_ERROR,"Out of memory allocating user data\n"); \
} \
} \
}
#endif
#else
#if defined (__TREE_RETURN)
#define MY_MALLOC_USER_DATA(tree,data_ptr) \
{ \
if (tree.u_data_size > 0) { \
MY_MALLOCN(data_ptr,(char *),tree.u_data_size,1); \
} \
}
#else
#define MY_MALLOC_USER_DATA(tree,data_ptr) \
{ \
if (tree.u_data_size > 0) { \
MY_MALLOCN(data_ptr,(char *),tree.u_data_size,1); \
} \
}
#endif
#endif
#if defined(__SLOW_MALLOC)
#define MY_FREE_USER_DATA(tree,data_ptr) \
{ \
if (data_ptr != NULL) { \
BSsbfree(data_ptr,&(tree.user_blocks)); \
} \
}
#else
#define MY_FREE_USER_DATA(tree,data_ptr) \
{ \
if (data_ptr != NULL) { \
MY_FREEN(data_ptr); \
} \
}
#endif
#if defined(__SLOW_MALLOC)
#define MY_FREE_TREE_NODE(tree,inptr) \
{ \
int i99; \
for (i99=0;i99<MAX_KEYS;i99++) { \
MY_FREE_USER_DATA(tree,inptr->data_ptr[i99]); \
} \
BSsbfree(inptr,&(tree.node_blocks)); \
}
#else
#define MY_FREE_TREE_NODE(tree,inptr) \
{ \
int i99; \
for (i99=0;i99<MAX_KEYS;i99++) { \
MY_FREE_USER_DATA(tree,inptr->data_ptr[i99]); \
} \
MY_FREEN(inptr); \
}
#endif
#if defined(__SLOW_MALLOC)
#if defined (__TREE_RETURN)
#define MY_GET_TREE_NODE(tree,inptr) \
{ \
int i99; \
if ((inptr = (BStree_node *) BSsbmalloc(&(tree.node_blocks))) == NULL) { \
MY_SETERRCN(MEM_ERROR,"Out of memory allocating node data\n"); \
} \
inptr->num_keys = 0; \
inptr->parent = NULL; \
for (i99=0;i99<MAX_KIDS;i99++) { \
inptr->child[i99] = NULL; \
} \
for (i99=0;i99<MAX_KEYS;i99++) { \
inptr->data_ptr[i99] = NULL; \
} \
}
#else
#define MY_GET_TREE_NODE(tree,inptr) \
{ \
int i99; \
if ((inptr = (BStree_node *) BSsbmalloc(&(tree.node_blocks))) == NULL) { \
MY_SETERRCN(MEM_ERROR,"Out of memory allocating node data\n"); \
} \
inptr->num_keys = 0; \
inptr->parent = NULL; \
for (i99=0;i99<MAX_KIDS;i99++) { \
inptr->child[i99] = NULL; \
} \
for (i99=0;i99<MAX_KEYS;i99++) { \
inptr->data_ptr[i99] = NULL; \
} \
}
#endif
#else
#if defined (__TREE_RETURN)
#define MY_GET_TREE_NODE(tree,inptr) \
{ \
int i99; \
MY_MALLOCN(inptr,(BStree_node *),sizeof(BStree_node),1); \
inptr->num_keys = 0; \
inptr->parent = NULL; \
for (i99=0;i99<MAX_KIDS;i99++) { \
inptr->child[i99] = NULL; \
} \
for (i99=0;i99<MAX_KEYS;i99++) { \
inptr->data_ptr[i99] = NULL; \
} \
}
#else
#define MY_GET_TREE_NODE(tree,inptr) \
{ \
int i99; \
MY_MALLOCN(inptr,(BStree_node *),sizeof(BStree_node),1); \
inptr->num_keys = 0; \
inptr->parent = NULL; \
for (i99=0;i99<MAX_KIDS;i99++) { \
inptr->child[i99] = NULL; \
} \
for (i99=0;i99<MAX_KEYS;i99++) { \
inptr->data_ptr[i99] = NULL; \
} \
}
#endif
#endif
#if defined(__SLOW_MALLOC)
#if defined (__TREE_RETURN)
#define MY_INIT_TREE(tree,user_data_size) \
{ \
tree.root = NULL; \
tree.u_data_size = user_data_size; \
if ((tree.user_blocks = (void *) BSsbinit(tree.u_data_size,MAX_KEYS*128)) \
== NULL) { \
MY_SETERRCN(MEM_ERROR,"Out of memory initing user data\n"); \
} \
if ((tree.node_blocks = (void *) BSsbinit(sizeof(BStree_node),128)) \
== NULL) { \
MY_SETERRCN(MEM_ERROR,"Out of memory initing node data\n"); \
} \
}
#else
#define MY_INIT_TREE(tree,user_data_size) \
{ \
tree.root = NULL; \
tree.u_data_size = user_data_size; \
if ((tree.user_blocks = (void *) BSsbinit(tree.u_data_size,MAX_KEYS*128)) \
== NULL) { \
MY_SETERRC(MEM_ERROR,"Out of memory initing user data\n"); \
} \
if ((tree.node_blocks = (void *) BSsbinit(sizeof(BStree_node),128)) \
== NULL) { \
MY_SETERRC(MEM_ERROR,"Out of memory initing node data\n"); \
} \
}
#endif
#else
#define MY_INIT_TREE(tree,user_data_size) \
{ \
tree.root = NULL; \
tree.u_data_size = user_data_size; \
}
#endif
#if defined(__SLOW_MALLOC)
#define MY_CLEAN_TREE(tree) \
{ \
BSmem_clean(&(tree.user_blocks)); \
BSmem_clean(&(tree.node_blocks)); \
}
#else
#define MY_CLEAN_TREE(tree)
#endif
/* ***************************** */
/* end of special memory section */
/* ***************************** */
#define MY_PRINT_NODE(tptr) \
{ \
int i99; \
if (tptr == NULL) { \
printf("NULL NODE\n"); \
} else { \
printf("Node has %d keys: ",tptr->num_keys); \
if (tptr->child[0] != NULL) { \
printf(" Child "); \
} else { \
printf(" NoChild "); \
} \
for (i99=0;i99<tptr->num_keys;i99++) { \
printf("%d ",tptr->keys[i99]); \
if (tptr->child[i99+1] != NULL) { \
printf(" Child "); \
} else { \
printf(" NoChild "); \
} \
} \
printf("\n"); \
} \
}
#define MY_NEXT_IN_TREE(node_ptr) \
{ \
BStree_node *curptr99, *prevptr99, *chkptr99; \
int done99, i99; \
curptr99 = node_ptr.ptr->child[node_ptr.ind+1]; \
if (curptr99 == NULL) { \
node_ptr.ind++; \
if (node_ptr.ind == node_ptr.ptr->num_keys) { \
chkptr99 = node_ptr.ptr; \
curptr99 = chkptr99->parent; \
done99 = FALSE; \
while ((curptr99 != NULL) && (! done99)) { \
for (i99=0;i99<curptr99->num_keys+1;i99++) { \
if (curptr99->child[i99] == chkptr99) break; \
} \
if (i99 < curptr99->num_keys) { \
done99 = TRUE; \
} else { \
chkptr99 = curptr99; \
curptr99 = curptr99->parent; \
} \
} \
node_ptr.ptr = curptr99; \
node_ptr.ind = i99; \
} \
} else { \
while (curptr99 != NULL) { \
prevptr99 = curptr99; \
curptr99 = curptr99->child[0]; \
} \
node_ptr.ptr = prevptr99; \
node_ptr.ind = 0; \
} \
}
#define IS_TREE_PTR_NULL(tree_ptr) ((tree_ptr.ptr == NULL)?1:0)
#define MY_FIRST_IN_TREE(tree,node_ptr) \
{ \
BStree_node *tptr99, *pptr99; \
tptr99 = tree.root; \
pptr99 = tptr99; \
while (tptr99 != NULL) { \
pptr99 = tptr99; \
tptr99 = tptr99->child[0]; \
} \
node_ptr.ptr = pptr99; \
node_ptr.ind = 0; \
}
#define MY_KEY_LT(key1,key2) (((key1) < (key2))?1:0)
#define MY_KEY_EQUAL(key1,key2) (((key1) == (key2))?1:0)
#define MY_MAKE_PARENT(inchild,inparent) \
{ \
if (inchild != NULL) inchild->parent = inparent; \
}
#define MY_PUT_IN_TREE(tree,inkey,inptr) \
{ \
int done99, i99; \
BStree_node *tptr99, *cur_right99, *tright99; \
char *cur_data99, *tdata99; \
int cur_key99, tkey99; \
int temp_keys99[MAX_KEYS+1]; \
BStree_node *temp_kids99[MAX_KEYS+1]; \
char *temp_data99[MAX_KEYS+1]; \
if (tree.root == NULL) { \
MY_GET_TREE_NODE(tree,tree.root); \
tree.root->num_keys = 1; \
tree.root->keys[0] = inkey; \
MY_MALLOC_USER_DATA(tree,tree.root->data_ptr[0]); \
} else { \
done99 = FALSE; \
tptr99 = inptr; \
cur_key99 = inkey; \
cur_right99 = NULL; \
MY_MALLOC_USER_DATA(tree,cur_data99); \
while (! done99) { \
if (tptr99 == NULL) { \
MY_GET_TREE_NODE(tree,tptr99); \
tptr99->num_keys = 1; \
tptr99->keys[0] = cur_key99; \
tptr99->data_ptr[0] = cur_data99; \
tptr99->child[0] = tree.root; \
tree.root->parent = tptr99; \
tptr99->child[1] = cur_right99; \
cur_right99->parent = tptr99; \
tree.root = tptr99; \
done99 = TRUE; \
} else if (tptr99->num_keys < MAX_KEYS) { \
MY_MAKE_PARENT(cur_right99,tptr99); \
tptr99->keys[tptr99->num_keys] = cur_key99; \
tptr99->child[tptr99->num_keys+1] = cur_right99; \
tptr99->data_ptr[tptr99->num_keys] = cur_data99; \
tptr99->num_keys++; \
for (i99=tptr99->num_keys-1;i99>0;i99--) { \
if (MY_KEY_LT(tptr99->keys[i99],tptr99->keys[i99-1])) { \
tkey99 = tptr99->keys[i99]; \
tright99 = tptr99->child[i99+1]; \
tdata99 = tptr99->data_ptr[i99]; \
tptr99->keys[i99] = tptr99->keys[i99-1]; \
tptr99->child[i99+1] = tptr99->child[i99]; \
tptr99->data_ptr[i99] = tptr99->data_ptr[i99-1]; \
tptr99->keys[i99-1] = tkey99; \
tptr99->child[i99] = tright99; \
tptr99->data_ptr[i99-1] = tdata99; \
} else { \
break; \
} \
} \
done99 = TRUE; \
} else { \
for (i99=0;i99<MAX_KEYS;i99++) { \
temp_keys99[i99] = tptr99->keys[i99]; \
temp_data99[i99] = tptr99->data_ptr[i99]; \
temp_kids99[i99] = tptr99->child[i99+1]; \
} \
temp_keys99[MAX_KEYS] = cur_key99; \
temp_data99[MAX_KEYS] = cur_data99; \
temp_kids99[MAX_KEYS] = cur_right99; \
for (i99=MAX_KEYS;i99>0;i99--) { \
if (MY_KEY_LT(temp_keys99[i99],temp_keys99[i99-1])) { \
tkey99 = temp_keys99[i99]; \
tright99 = temp_kids99[i99]; \
tdata99 = temp_data99[i99]; \
temp_keys99[i99] = temp_keys99[i99-1]; \
temp_kids99[i99] = temp_kids99[i99-1]; \
temp_data99[i99] = temp_data99[i99-1]; \
temp_keys99[i99-1] = tkey99; \
temp_kids99[i99-1] = tright99; \
temp_data99[i99-1] = tdata99; \
} else { \
break; \
} \
} \
tptr99->num_keys = MIN_KEYS; \
for (i99=0;i99<MIN_KEYS;i99++) { \
tptr99->keys[i99] = temp_keys99[i99]; \
tptr99->child[i99+1] = temp_kids99[i99]; \
MY_MAKE_PARENT(tptr99->child[i99+1],tptr99); \
tptr99->data_ptr[i99] = temp_data99[i99]; \
} \
for (i99=MIN_KEYS;i99<MAX_KEYS;i99++) { \
tptr99->data_ptr[i99] = NULL; \
} \
MY_GET_TREE_NODE(tree,cur_right99); \
cur_right99->num_keys = MIN_KEYS; \
cur_right99->child[0] = temp_kids99[MIN_KEYS]; \
MY_MAKE_PARENT(cur_right99->child[0],cur_right99); \
for (i99=0;i99<MIN_KEYS;i99++) { \
cur_right99->keys[i99] = temp_keys99[i99+MIN_KEYS+1]; \
cur_right99->child[i99+1] = temp_kids99[i99+MIN_KEYS+1]; \
MY_MAKE_PARENT(cur_right99->child[i99+1],cur_right99); \
cur_right99->data_ptr[i99] = temp_data99[i99+MIN_KEYS+1]; \
} \
cur_key99 = temp_keys99[MIN_KEYS]; \
cur_data99 = temp_data99[MIN_KEYS]; \
tptr99 = tptr99->parent; \
} \
} \
} \
}
#define MY_SEARCH_TREE(tree,inkey,found,node_ptr) \
{ \
BStree_node *tptr99, *pptr99; \
int down99, i99; \
tptr99 = tree.root; \
pptr99 = tptr99; \
found = FALSE; \
while ((tptr99 != NULL) && (! found)) { \
down99 = FALSE; \
pptr99 = tptr99; \
for (i99=0;i99<tptr99->num_keys;i99++) { \
if (MY_KEY_EQUAL(inkey,tptr99->keys[i99])) { \
found = TRUE; \
down99 = TRUE; \
node_ptr.ptr = tptr99; \
node_ptr.ind = i99; \
break; \
} else if (MY_KEY_LT(inkey,tptr99->keys[i99])) { \
down99 = TRUE; \
tptr99 = tptr99->child[i99]; \
break; \
} \
} \
if (! down99) { \
tptr99 = tptr99->child[tptr99->num_keys]; \
} \
} \
if (!found) { \
node_ptr.ptr = pptr99; \
} \
}
#define MY_INSERT_TREE_NODE(tree,inkey,found,node_ptr,key_count) \
{ \
MY_SEARCH_TREE(tree,inkey,found,node_ptr); \
if (!found) { \
key_count++; \
MY_PUT_IN_TREE(tree,inkey,(node_ptr.ptr)); \
MY_SEARCH_TREE(tree,inkey,found,node_ptr); \
found = FALSE; \
} \
}
#define MY_GET_TREE_DATA(node_ptr) node_ptr.ptr->data_ptr[node_ptr.ind]
#define MY_GET_TREE_KEY(node_ptr) node_ptr.ptr->keys[node_ptr.ind]
#define MY_FREE_TREE(tree) \
{ \
BStree_node *curptr99, *tptr99; \
int i99, found99; \
curptr99 = tree.root; \
while (curptr99 != NULL) { \
found99 = FALSE; \
for (i99=0;i99<curptr99->num_keys+1;i99++) { \
tptr99 = curptr99->child[i99]; \
if (tptr99 != NULL) { \
curptr99->child[i99] = NULL; \
curptr99 = tptr99; \
found99 = TRUE; \
break; \
} \
} \
if (! found99) { \
tptr99 = curptr99; \
curptr99 = curptr99->parent; \
MY_FREE_TREE_NODE(tree,tptr99); \
} \
} \
MY_CLEAN_TREE(tree); \
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1